JQuery 或 vanilla Javascript 中的 DOM Mutation 事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7692730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
DOM Mutation event in JQuery or vanilla Javascript
提问by aziz punjani
Are there any DOM mutation events in JQuery or in vanilla Javascript that fire cross browser?
在 JQuery 或 vanilla Javascript 中是否有任何 DOM 突变事件会触发跨浏览器?
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.
澄清一下,假设我的页面上有一个脚本,它在正文中插入一个 div。我无权访问脚本,也不知道 div 何时插入。我想知道是否有我可以添加侦听器的 DOM 突变事件,以了解何时插入元素。我知道我可以使用计时器来定期检查插入,但是,我真的不喜欢这会带来的开销。
回答by Daniel Mendel
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:
这当然是一个 hack,但为什么不修补用于插入节点的底层 DOM 方法呢?有几种方法可以做到这一点:
A. You know what specificelement 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);
}
B. You know what typeof element will be appended to:
乙。你知道什么类型的元素将被附加到:
HTMLDivElement.prototype.__appendChild = HTMLDivElement.prototype.appendChild;
HTMLDivElement.prototype.appendChild = function(){
alert('new item added');
HTMLDivElement.prototype.__appendChild(this,arguments);
}
(Note that solution Bis not supported by IE < 8
or any other browser which does not support DOM prototypes.)
(请注意,解决方案B不受IE < 8
或任何其他不支持 DOM 原型的浏览器的支持。)
This same technique could just as easily be used on all the underlying DOM mutation functions such as insertBefore
, replaceChild
or removeChild
.
同样的技术可以很容易地用于所有底层 DOM 突变函数,例如insertBefore
,replaceChild
或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 alladditions regardless of type ANDmake sure it works across all browserseverything but IE < 8
? (see example C below)
这是一般的想法,这些演示几乎可以适用于任何其他用例 - 假设您想撒网并捕获所有添加内容,而不管类型如何,并确保它适用于所有浏览器,但IE < 8
? (参见下面的示例 C)
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.
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>');
UPDATE 2
更新 2
As Tim Downcommented, 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'
.
正如Tim Down评论的那样,上述解决方案也无法使用,IE < 8
因为appendChild
is not aFunction
并且不支持call
or apply
。我想setInterval
如果typeof document.body.appendChild !== 'function'
.
回答by Kai
There are some deprecatedDOM mutation events, such as DOMNodeInserted
and DOMNodeInsertedIntoDocument
that still work for me in Chrome 14 and IE9.
有一些已弃用的DOM 突变事件,例如DOMNodeInserted
和DOMNodeInsertedIntoDocument
在 Chrome 14 和 IE9 中仍然适用于我。
See an example at http://jsfiddle.net/Kai/WTJq6/
请参阅http://jsfiddle.net/Kai/WTJq6/ 上的示例
See them all on the W3C draft at http://www.w3.org/TR/DOM-Level-3-Events/
在http://www.w3.org/TR/DOM-Level-3-Events/的 W3C 草案中查看所有这些内容
回答by user1028943
JCADE (JQuery Create and Destroy Events) will do this. It uses behaviorsfor IE and DOM mutation eventsfor other browsers. It does not use timing events and does not wrap JQuery methods like livequery.
JCADE(JQuery 创建和销毁事件)将执行此操作。它为其他浏览器使用IE 和DOM 突变事件的行为。它不使用计时事件,也不像 livequery 那样包装 JQuery 方法。
https://github.com/snesin/jcade
https://github.com/snesin/jcade
$( document ).create( "a", function( event ) { alert( event.target ); });
回答by Adam Terlson
Not without a plugin, I believe, but I wouldn't be surprised if I'm wrong.
我相信不是没有插件,但如果我错了,我不会感到惊讶。
My research has found a a few to choose from.
我的研究发现了一些可供选择。
Here's one: http://plugins.jquery.com/project/mutation-events
这是一个:http: //plugins.jquery.com/project/mutation-events
Here's another: https://www.adaptavist.com/display/jQuery/Mutation+Events
这是另一个:https: //www.adaptavist.com/display/jQuery/Mutation+Events
回答by Val
If you are looking for an alternative to this method, here is http://www.jqui.net/jquery-projects/jquery-mutate-official/which can also allow you to add events yourself and keep a watch for almost any change, class name change, height change, width change.
如果您正在寻找此方法的替代方法,请访问http://www.jqui.net/jquery-projects/jquery-mutate-official/,它也可以让您自己添加事件并留意几乎所有更改,类名改变,高度改变,宽度改变。
回答by Simon Steinberger
The livequeryplugin can be used for this. In version 1.x a timer was used to periodically check for any changes. However, the newer version 2.x branch seems to be working without periodical timeout (untested).
该的liveQuery插件可以用于此目的。在 1.xa 版本中,计时器用于定期检查任何更改。但是,较新版本的 2.x 分支似乎可以在没有定期超时的情况下工作(未经测试)。