web-dev-qa-db-fra.com

Incendie de l'événement jQuery lors du changement de div

J'ai un div dont le contenu peut changer de différentes manières: par exemple, tout son contenu peut être rechargé via innerHTML ou des nœuds peuvent être ajoutés via des méthodes DOM. Cela peut se produire via JavaScript javascript ou indirectement via des appels à l'API jQuery ou via d'autres bibliothèques.

Je veux exécuter du code lorsque le contenu de la div change, mais j'ai absolument aucun contrôle sur comment cela changera . En effet, je conçois un widget qui peut être utilisé par d’autres personnes, qui sont libres de modifier le contenu de leurs divs comme elles le souhaitent. Lorsque le contenu interne de cette div change, la forme du widget doit également être mise à jour.

J'utilise jQuery. Y at-il un moyen de capturer l'événement que le contenu de cette div a changé, peu importe ce qui s'est passé?

58
Andrea

Vous pouvez utiliser DOMNodeInserted et DOMNodeRemoved pour vérifier si des éléments sont ajoutés ou supprimés. Malheureusement, IE ne supporte pas cela.

$('#myDiv').bind('DOMNodeInserted DOMNodeRemoved', function(event) {
    if (event.type == 'DOMNodeInserted') {
        alert('Content added! Current content:' + '\n\n' + this.innerHTML);
    } else {
        alert('Content removed! Current content:' + '\n\n' + this.innerHTML);
    }
});

Mise à jour

Vous pouvez enregistrer le contenu initial et les modifications futures avec .data(). Voici un exemple.

var div_eTypes = [],
    div_changes = [];
$(function() {
    $('#myDiv').each(function() {
        this['data-initialContents'] = this.innerHTML;
    }).bind('DOMNodeInserted DOMNodeRemoved', function(event) {
        div_eTypes.concat(e.type.match(/insert|remove/));
        div_changes.concat(this.innerHTML);
    });
});

Exemple de sortie:

> $('#myDiv').data('initialContents');
"<h1>Hello, world!</h1><p>This is an example.</p>"
> div_eTypes;
["insert", "insert", "remove"]
> div_changes;
["<iframe src='http://example.com'></iframe>", "<h4>IANA — Example domains</h4><iframe src='http://example.com'></iframe>", "<h4>IANA – Example domains</h4>"]

Mise à jour 2

Vous voudrez peut-être aussi inclure DOMSubtreeModified, car j'ai découvert que DOMNodeInserted et DOMNodeRemoved ne se déclenchent pas si l'élément innerHTML d'un élément est remplacé directement . Cela ne fonctionne toujours pas dans IE, mais au moins cela fonctionne bien dans les autres navigateurs.

70
nyuszika7h

essayez quelque chose comme ça ...

    $('#divId').bind('DOMNodeInserted', function(event) {
             alert('inserted ' + event.target.nodeName + // new node
           ' in ' + event.relatedNode.nodeName); // parent
       });

IE ne supporte pas cette propriété, mais je pense que l'événement le plus proche est l'événement propertychange, qui se déclenche en réponse à une modification d'un attribut ou de la propriété CSS d'un élément, mais ne se déclenche pas en réponse à innerHTML changer, ce qui aurait été proche de ce que vous vouliez.

une autre solution possible consiste à remplacer la fonction de manipulation de jquery ...

Regardez cette discussion .. Moyen privilégié de modifier des éléments qui n'ont pas encore été créés (en dehors des événements)

7
Vivek

Il n'y a pas un tel événement (onChange) dans javascript ou jQuery, vous devez créer un événement personnalisé.

Une solution pourrait utiliser lowpro pour associer un comportement à cet élément que vous voulez contrôler. Ce comportement sérialiserait l'élément, puis créerait un sondage qui vérifierait toutes les x millisecondes pour voir si l'élément avait été modifié, puis déclencher votre événement personnalisé. sur cet élément.

Vous avez quelques exemples sur la façon d'utiliser lowpro avec jQuery ici: http://www.learningjquery.com/2008/05/using-low-pro-for-jquery

Bonne chance!

1
Fernando Diaz Garrido