JQuery或Javascript中的DOM突变事件

DOM Mutation event in JQuery or vanilla Javascript

本文关键字:突变 事件 DOM 中的 Javascript JQuery      更新时间:2023-09-26

是否有任何DOM突变事件在JQuery或在香草Javascript火跨浏览器?

为了澄清,假设我的页面上有一个脚本,它在正文中插入了一个div。我没有访问脚本,我不知道何时div已被插入。我想知道是否有一个DOM突变事件,我可以为其添加一个侦听器,以知道何时插入了一个元素。我知道我可以使用计时器来定期检查插入,但我真的不喜欢这样带来的开销

这当然是一个hack,但是为什么不修补用于插入节点的底层DOM方法呢?有几种方法可以做到这一点:

。您知道特定的元素将被附加到:

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

A

你知道元素的类型将被附加到:

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

小提琴演示B

(注意解决方案B不支持IE < 8或任何其他不支持DOM原型的浏览器)

同样的技术可以很容易地用于所有底层DOM突变函数,如insertBefore, replaceChildremoveChild

这是一般的想法,这些演示可以适用于几乎任何其他用例——假设你想撒网并捕获所有的添加,而不管类型确保它在所有浏览器除了IE < 8的一切都有效?(见下面的例子C)


C。递归遍历DOM,交换每个元素上的函数以触发回调,然后将相同的补丁应用于附加的任何子元素。

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>');
C

UPDATE 2

正如Tim Down评论的那样,上述解决方案也不能在IE < 8中工作,因为appendChild不是Function,也不支持callapply。我想,如果typeof document.body.appendChild !== 'function' .

,你总是可以回到笨拙但可靠的setInterval方法。

有一些弃用的 DOM突变事件,如DOMNodeInsertedDOMNodeInsertedIntoDocument,仍然为我在Chrome 14和IE9中工作。

参见http://jsfiddle.net/Kai/WTJq6/

的示例

在http://www.w3.org/TR/DOM-Level-3-Events/

的W3C草案中查看它们。

JCADE (JQuery创建和销毁事件)将会做到这一点。它对IE使用行为,对其他浏览器使用DOM突变事件。它不使用定时事件,也不像livequery那样包装JQuery方法。

https://github.com/snesin/jcade

<>之前$(文档)。创建("a",函数(事件){警报(事件。目标);});

没有插件,我相信,但如果我错了,我也不会感到惊讶。

我的研究发现了一些可供选择的。

这里有一个:http://plugins.jquery.com/project/mutation-events

这里是另一个:https://www.adaptavist.com/display/jQuery/Mutation+Events

如果您正在寻找替代此方法的方法,这里是http://www.jqui.net/jquery-projects/jquery-mutate-official/,它也可以让您自己添加事件,并保持监视几乎任何更改,类名称更改,高度更改,宽度更改。

livequery插件可用于此。在版本1中。使用计时器定期检查任何更改。然而,较新的版本2。