web-dev-qa-db-fra.com

Evénement jQuery: détecter les modifications apportées au code HTML / texte d'un div

J'ai un div dont le contenu change tout le temps, que ce soit ajax requests, jquery functions, blur etc. etc.

Existe-t-il un moyen de détecter tout changement sur ma division à tout moment?

Je ne veux pas utiliser des intervalles ou une valeur par défaut cochée.

Quelque chose comme ça ferait

$('mydiv').contentchanged() {
 alert('changed')
}
248
BoqBoq

Si vous ne voulez pas utiliser timer et cocher innerHTML, vous pouvez essayer cet événement.

$('mydiv').bind("DOMSubtreeModified",function(){
  alert('changed');
});

Plus de détails et les données de support du navigateur sont Ici .

Attention: dans les versions plus récentes de jQuery, bind () est obsolète. Vous devez donc utiliser on () à la place:

$("body").on('DOMSubtreeModified', "mydiv", function() {
    alert('changed');
});
369
iman

Puisque $("#selector").bind() est obsolète , vous devez utiliser:

$("body").on('DOMSubtreeModified', "#selector", function() {
    // code here
});
44
Artley

Tu peux essayer ça

$('.myDiv').bind('DOMNodeInserted DOMNodeRemoved', function() {

});

mais cela pourrait ne pas fonctionner dans Internet Explorer, je ne l'ai pas testé

39
user1790464

Vous recherchez MutationObserver ou Événements de mutation . Ni sont pris en charge partout, ni sont trop mal considérés par le monde du développeur.

Si vous savez (et pouvez vous assurer que) la taille de la div changera, vous pourrez peut-être utiliser l'événement crossbrowser resize resize .

33
rodneyrehm

Utiliser Javascript MutationObserver

  //More Details https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
 // select the target node
var target = document.querySelector('mydiv')
// create an observer instance
var observer = new MutationObserver(function(mutations) {
  console.log($('mydiv').text());   
});
// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true };
// pass in the target node, as well as the observer options
observer.observe(target, config);
31
PPB

Le code suivant fonctionne pour moi.

$("body").on('DOMSubtreeModified', "mydiv", function() {
    alert('changed');
});

J'espère que ça va aider quelqu'un :)

19
Sanchit Gupta

Il n’existe pas de solution intégrée à ce problème, c’est un problème de conception et de structure de codage.

Vous pouvez utiliser un modèle éditeur/abonné. Pour cela, vous pouvez utiliser des événements personnalisés jQuery ou votre propre mécanisme d’événement.

Première,

function changeHtml(selector, html) {
    var elem = $(selector);
    jQuery.event.trigger('htmlchanging', { elements: elem, content: { current: elem.html(), pending: html} });
    elem.html(html);
    jQuery.event.trigger('htmlchanged', { elements: elem, content: html });
}

Maintenant, vous pouvez souscrire aux événements divhtmlchanging/divhtmlchanged comme suit:

$(document).bind('htmlchanging', function (e, data) {
    //your before changing html, logic goes here
});

$(document).bind('htmlchanged', function (e, data) {
    //your after changed html, logic goes here
});

Maintenant, vous devez changer vos changements de contenu div avec cette fonction changeHtml(). Vous pouvez donc surveiller ou effectuer les modifications nécessaires en conséquence, car l'argument de données de rappel de rappel qui contient les informations.

Vous devez changer le code HTML de votre div comme ceci;

changeHtml('#mydiv', '<p>test content</p>');

Et aussi, vous pouvez l’utiliser pour n’importe quel élément HTML, à l’exception de l’élément input. Quoi qu'il en soit, vous pouvez le modifier pour l'utiliser avec n'importe quel élément.

Utilisez MutationObserver comme indiqué dans cet extrait fourni par Mozilla , et adapté de cet article de blog

Alternativement, vous pouvez utiliser l'exemple JQuery visible sur ce lien

Chrome 18+, Firefox 14+, IE 11+, Safari 6+

// Select the node that will be observed for mutations
var targetNode = document.getElementById('some-id');

// Options for the observer (which mutations to observe)
var config = { attributes: true, childList: true };

// Callback function to execute when mutations are observed
var callback = function(mutationsList) {
    for(var mutation of mutationsList) {
        if (mutation.type == 'childList') {
            console.log('A child node has been added or removed.');
        }
        else if (mutation.type == 'attributes') {
            console.log('The ' + mutation.attributeName + ' attribute was modified.');
        }
    }
};

// Create an observer instance linked to the callback function
var observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
observer.observe(targetNode, config);

// Later, you can stop observing
observer.disconnect();
8
Anthony Awuley

Vous pouvez stocker l'ancien innerHTML de la div dans une variable. Définissez un intervalle pour vérifier si l'ancien contenu correspond au contenu actuel. Quand ce n'est pas vrai, fais quelque chose.

3
codelove

Essayez le MutationObserver:

support du navigateur: http://caniuse.com/#feat=mutationobserver

<html>
  <!-- example from Microsoft https://developer.Microsoft.com/en-us/Microsoft-Edge/platform/documentation/dev-guide/dom/mutation-observers/ -->

  <head>
    </head>
  <body>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script type="text/javascript">
      // Inspect the array of MutationRecord objects to identify the nature of the change
function mutationObjectCallback(mutationRecordsList) {
  console.log("mutationObjectCallback invoked.");

  mutationRecordsList.forEach(function(mutationRecord) {
    console.log("Type of mutation: " + mutationRecord.type);
    if ("attributes" === mutationRecord.type) {
      console.log("Old attribute value: " + mutationRecord.oldValue);
    }
  });
}
      
// Create an observer object and assign a callback function
var observerObject = new MutationObserver(mutationObjectCallback);

      // the target to watch, this could be #yourUniqueDiv 
      // we use the body to watch for changes
var targetObject = document.body; 
      
// Register the target node to observe and specify which DOM changes to watch
      
      
observerObject.observe(targetObject, { 
  attributes: true,
  attributeFilter: ["id", "dir"],
  attributeOldValue: true,
  childList: true
});

// This will invoke the mutationObjectCallback function (but only after all script in this
// scope has run). For now, it simply queues a MutationRecord object with the change information
targetObject.appendChild(document.createElement('div'));

// Now a second MutationRecord object will be added, this time for an attribute change
targetObject.dir = 'rtl';


      </script>
    </body>
  </html>
1
juFo

Ajouter du contenu à un div, que ce soit via jQuery ou directement via DOM-API, utilise par défaut la fonction .appendChild(). Ce que vous pouvez faire est de remplacer la fonction .appendChild() de l'objet actuel et d'y implémenter un observateur. Maintenant que nous avons remplacé notre fonction .appendChild(), nous devons l’emprunter à un autre objet pour pouvoir ajouter le contenu. Pour cela, nous appelons la .appendChild() d'un autre div pour finalement ajouter le contenu. Bien sûr, cela compte aussi pour la .removeChild().

var obj = document.getElementById("mydiv");
    obj.appendChild = function(node) {
        alert("changed!");

        // call the .appendChild() function of some other div
        // and pass the current (this) to let the function affect it.
        document.createElement("div").appendChild.call(this, node);
        }
    };

Ici vous pouvez trouver un exemple naïf. Vous pouvez l'étendre par vous-même, je suppose. http://jsfiddle.net/RKLmA/31/

Au fait: cela montre que JavaScript est conforme au principe OpenClosed. :)

0
Andries