简体   繁体   中英

DOM Mutation event in JQuery or vanilla Javascript

Are there any DOM mutation events in JQuery or in vanilla Javascript that fire cross browser?

To clarify, say I have a script on my page which inserts a div into the body. I don't have access to the script and I don't know when the div has been inserted. I was wondering if there's a DOM mutation event that I can add a listener for, to know when an element has been inserted. I know I can use a timer to periodically check for the insertion but, I don't really like the overhead that this would impose.

This is certainly a hack, but why not patch the underlying DOM methods used to insert the nodes? There are a couple ways to do this:

A . You know what specific element will be appended to:

var c = document.getElementById('#container');
c.__appendChild = c.appendChild;
c.appendChild = function(){
     alert('new item added');
     c.__appendChild.apply(c, arguments); 
}

fiddle demo for A

B . You know what type of element will be appended to:

HTMLDivElement.prototype.__appendChild = HTMLDivElement.prototype.appendChild;
HTMLDivElement.prototype.appendChild = function(){
    alert('new item added');
    HTMLDivElement.prototype.__appendChild(this,arguments); 
}

fiddle demo for B

(Note that solution B is not supported by IE < 8 or any other browser which does not support DOM prototypes.)

This same technique could just as easily be used on all the underlying DOM mutation functions such as insertBefore , replaceChild or removeChild .

That's the general idea, these demos could be adapted for pretty much any other use case -- say you want to cast a wide net and catch all additions regardless of type AND make sure it works across all browsers everything but IE < 8 ? (see example C below)


UPDATE

C. Recursively walk the DOM, swap out the function on every element to trigger a callback, and then apply the same patch to any children being appended.

var DOMwatcher = function(root, callback){
  var __appendChild = document.body.appendChild;

  var patch = function(node){
    if(typeof node.appendChild !== 'undefined' && node.nodeName !== '#text'){
      node.appendChild = function(incomingNode){
        callback(node, incomingNode);
        patch(incomingNode);
        walk(incomingNode);
        __appendChild.call(node, incomingNode);
      };
    }
    walk(node);  
  };

  var walk = function(node){
    var i = node.childNodes.length;
    while(i--){
      patch(node.childNodes[i]);
    }
  };

  patch(root);

};

DOMwatcher(document.body, function(targetElement, newElement){ 
   alert('append detected');    
});

$('#container ul li').first().append('<div><p>hi</p></div>');
$('#container ul li div p').append('<a href="#foo">bar</a>');

fiddle demo for C

UPDATE 2

As Tim Down commented, the above solution also won't work in IE < 8 because appendChild is not a Function and does not support call or apply . I suppose you could always fall back to the clunky but trusty setInterval method if typeof document.body.appendChild !== 'function' .

There are some deprecated DOM mutation events, such as DOMNodeInserted and DOMNodeInsertedIntoDocument that still work for me in Chrome 14 and IE9.

See an example at http://jsfiddle.net/Kai/WTJq6/

See them all on the W3C draft at http://www.w3.org/TR/DOM-Level-3-Events/

JCADE (JQuery Create and Destroy Events) will do this. It uses for IE and for other browsers. It does not use timing events and does not wrap JQuery methods like livequery.

https://github.com/snesin/jcade

$( document ).create( "a", function( event ) {
      alert( event.target );
    });

Not without a plugin, I believe, but I wouldn't be surprised if I'm wrong.

My research has found aa few to choose from.

Here's one: http://plugins.jquery.com/project/mutation-events

Here's another: https://www.adaptavist.com/display/jQuery/Mutation+Events

如果您正在寻找此方法的替代方法,请访问http://www.jqui.net/jquery-projects/jquery-mutate-official/ ,它还可以让您自己添加事件并随时关注任何更改,班级名称变更,身高变化,宽度变化。

The livequery plugin can be used for this. In version 1.xa timer was used to periodically check for any changes. However, the newer version 2.x branch seems to be working without periodical timeout (untested).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM