在 JQuery 或 vanilla Javascript 中是否有任何触发跨浏览器的 DOM 突变事件?
为了澄清,假设我的页面上有一个脚本,它将一个 div 插入正文。我无权访问脚本,也不知道何时插入了 div。我想知道是否有一个 DOM 突变事件可以添加一个侦听器,以了解何时插入了一个元素。我知道我可以使用计时器来定期检查插入,但是,我真的不喜欢这会带来的开销。
在 JQuery 或 vanilla Javascript 中是否有任何触发跨浏览器的 DOM 突变事件?
为了澄清,假设我的页面上有一个脚本,它将一个 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);
}
乙。您知道将附加什么类型的元素:
HTMLDivElement.prototype.__appendChild = HTMLDivElement.prototype.appendChild;
HTMLDivElement.prototype.appendChild = function(){
alert('new item added');
HTMLDivElement.prototype.__appendChild(this,arguments);
}
(请注意,解决方案B不受IE < 8
任何其他不支持 DOM 原型的浏览器的支持。)
同样的技术可以很容易地用于所有底层 DOM 变异函数,例如insertBefore
,replaceChild
或removeChild
.
这是一般的想法,这些演示几乎可以适用于任何其他用例——比如你想广撒网并捕捉所有添加的内容,而不管类型如何,并确保它适用于所有浏览器,除了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>');
更新 2
正如Tim Down评论的那样,上述解决方案也不起作用,IE < 8
因为appendChild
is not aFunction
也不支持call
or apply
。我想setInterval
如果typeof document.body.appendChild !== 'function'
.
有一些已弃用的DOM 突变事件,例如在 Chrome 14DOMNodeInserted
和DOMNodeInsertedIntoDocument
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
$( 文档 ).create( "a", function( event ) { 警报(事件.目标); });
我相信,不是没有插件,但如果我错了,我不会感到惊讶。
我的研究发现有一些可供选择。
这是一个: 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.xa 版本中,计时器用于定期检查任何更改。但是,较新版本的 2.x 分支似乎可以在没有定期超时的情况下工作(未经测试)。