web-dev-qa-db-fra.com

Détecter les changements de contenu d'élément avec jQuery

La fonction change() fonctionne et détecte les modifications des éléments de formulaire, mais existe-t-il un moyen de détecter le moment où le contenu d'un élément DOM a été modifié?

Cela ne fonctionne pas, sauf si #content est un élément de formulaire.

$("#content").change( function(){
    // do something
});

Je veux que cela se déclenche lorsque vous faites quelque chose comme:

$("#content").html('something');

De plus, la fonction html() ou append() ne dispose pas de rappel.

Aucune suggestion?

111
Elzo Valugi

Ce sont événements de mutation .

Je n'ai pas utilisé les API d'événement de mutation dans jQuery, mais une recherche rapide m'a conduit à ce projet sur GitHub. Je ne suis pas au courant de la maturité du projet.

24
jrharshath

Je sais que ce message date d'un an, mais j'aimerais proposer une approche de solution différente à ceux qui ont un problème similaire:

  1. L'événement de modification jQuery est utilisé uniquement dans les champs de saisie de l'utilisateur, car si quelque chose d'autre est manipulé (par exemple, un div), cette manipulation provient du code. Alors, trouvez où se produit la manipulation, puis ajoutez ce dont vous avez besoin.

  2. Mais si ce n'est pas possible pour une raison quelconque (vous utilisez un plugin compliqué ou vous ne trouvez aucune possibilité de "rappel"), alors l'approche jQuery que je suggérerais est la suivante:

    une. Pour une manipulation DOM simple, utilisez jQuery chaining and traversing, $("#content").html('something').end().find(whatever)....

    b. Si vous souhaitez faire autre chose, utilisez bind de jQuery avec un événement personnalisé et triggerHandler

    $("#content").html('something').triggerHandler('customAction');
    
    $('#content').unbind().bind('customAction', function(event, data) {
       //Custom-action
    });
    

Voici un lien vers le gestionnaire de déclencheur jQuery: http://api.jquery.com/triggerHandler/

69
Kyle

qu'en est-il de http://jsbin.com/esepal/2

$(document).bind("DOMSubtreeModified",function(){
  console.log($('body').width() + ' x '+$('body').height());
})

Cet événement est déconseillé en faveur de Mutation Observer API

15
FDisk

Le navigateur ne déclenche pas l'événement onchange pour les éléments <div>.

Je pense que le raisonnement derrière cela est que ces éléments ne changeront pas à moins d'être modifiés par javascript. Si vous devez déjà modifier l'élément vous-même (plutôt que l'utilisateur le fait), vous pouvez simplement appeler le code d'accompagnement approprié en même temps que vous modifiez l'élément, comme suit:

 $("#content").html('something').each(function() { });

Vous pouvez également déclencher manuellement un événement comme celui-ci:

 $("#content").html('something').change();

Si aucune de ces solutions ne fonctionne dans votre situation, pourriez-vous s'il vous plaît donner plus d'informations sur ce que vous essayez spécifiquement d'accomplir?

13
TM.

Essayez de vous lier à l'événement DOMSubtreeModified, voir que le test fait également partie du DOM.

voir ce post ici sur SO:

comment-je-surveiller-le-dom-pour-modifications

10
Colin

Essayez ceci, il a été créé par James Padolsey (J-P ici sur SO) et fait exactement ce que vous voulez (je pense)

http://james.padolsey.com/javascript/monitoring-dom-properties/

10
Pim Jager

Et avec HTML5, nous avons observateurs de mutation DOM natifs .

7
Elzo Valugi

Ce n'est pas strictement une réponse jQuery - mais il est utile de le mentionner pour le débogage.

Dans Firebug, vous pouvez cliquer avec le bouton droit sur un élément de l'arborescence DOM et configurer "Interrompre le changement d'attribut":

Element right-click in Firebug with Break on Attribute Change highlighted

Lorsqu'un attribut est modifié dans un script, la fenêtre de débogage apparaîtra et vous pourrez suivre ce qui se passe. Il existe également une option pour l’insertion et la suppression d’éléments ci-dessous (masquée inutilement par la fenêtre contextuelle du screengrab).

3
John Reid

Essayez le plugin livequery. Cela semble fonctionner pour quelque chose de similaire que je fais.

http://docs.jquery.com/Plugins/livequery

2
Arpit

Je développe une petite bibliothèque JS appelée mutabor ( https://github.com/eskat0n/mutabor ) qui visait à simplifier l'utilisation des événements de mutation DOM. Voir demo.html pour des exemples.

2
Eskat0n

Vous pouvez ajouter une option de rappel à la fonction html (ou n’importe laquelle):

$.fn.oldHtml = $.fn.html;
$.fn.html = function(html,fn){
  fn = fn || function(){};
  var result =  this.oldHtml(html);
  fn();
  return result;
};
$('body').html(11,function(){alert("haha");});

Démo ici.

Vous effectuez la modification sur un élément, mais l'élément n'est obligé de changer que par quelque chose que vous devez attraper.

1
user669677

Un moyen simple et efficace d'y parvenir consiste souvent à savoir quand et où vous modifiez le DOM.

Vous pouvez le faire en créant une fonction centrale toujours responsable de la modification du DOM. Vous effectuez ensuite le nettoyage dont vous avez besoin sur l'élément modifié dans cette fonction.

Dans une application récente, je n'avais pas besoin d'action immédiate et j'ai donc utilisé un rappel pour la fonction handly load (), pour ajouter une classe à tous les éléments modifiés, puis mis à jour tous les éléments modifiés toutes les quelques secondes à l'aide d'un minuteur setInterval.

$($location).load("my URL", "", $location.addClass("dommodified"));

Ensuite, vous pouvez le gérer comme vous le souhaitez - par exemple.

setInterval("handlemodifiedstuff();", 3000); 
function handlemodifiedstuff()
{
    $(".dommodified").each(function(){/* Do stuff with $(this) */});
}
1
Antony Carthy

Nous pouvons y parvenir en utilisant Événements de mutation . Selon www.w3.org, le module d'événement de mutation est conçu pour permettre la notification de tout changement dans la structure d'un document, y compris les modifications d'attr et de texte. Pour plus de détails ÉVÉNEMENTS DE MUTATION

Par exemple :

$("body").on('DOMSubtreeModified', "#content", function() {
    alert('Content Modified'); // do something
});
0
Sanchit Gupta

J'ai écrit un extrait qui vérifie le changement d'un élément lors d'un événement.

Donc, si vous utilisez du code javascript tiers ou quelque chose et que vous avez besoin de savoir quand quelque chose apparaît ou change lorsque vous avez cliqué dessus, vous pouvez le faire.

Pour l'extrait ci-dessous, supposons que vous ayez besoin de savoir quand le contenu d'un tableau change après avoir cliqué sur un bouton.

$('.button').live('click', function() {

            var tableHtml = $('#table > tbody').html();
            var timeout = window.setInterval(function(){

                if (tableHtml != $('#table > tbody').
                    console.log('no change');
                } else {
                    console.log('table changed!');
                    clearInterval(timeout);
                }

            }, 10);
        });

Pseudo Code:

  • Une fois que vous avez cliqué sur un bouton
  • le html de l'élément que vous souhaitez modifier est capturé
  • nous vérifions ensuite continuellement le code HTML de l'élément
  • quand nous trouvons le html différent, nous arrêtons la vérification
0
Andrew Atkinson