已知DOMNodeInserted使动态页面变慢,MDN even recommends完全没有使用它,但没有提供任何替代方案。
我对插入的元素不感兴趣,我只需要知道一些脚本何时修改DOM。是否有更好的替代突变事件监听器(可能是nsiTimer中的getElementsByTagName)?
答案 0 :(得分:44)
如果您要创建针对最近移动电话和较新版本浏览器(Firefox 5 +,Chrome 4 +,Safari 4 +,iOS Safari 3 +,Android 2.1+)的网络应用,您可以使用以下代码为插入dom节点创建一个很棒的事件,它甚至可以在节点的最初部分静态标记上运行!
以下是完整帖子的链接,例如:http://www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/
关于变异观察者的注意事项:虽然最近的浏览器中较新的Mutation Observers功能非常适合监视简单的插入和DOM的更改,但是要明白这个方法可以用来做更多的事情,因为它允许您监视任何CSS规则匹配。这对于许多用例来说非常强大,所以我把它包装在这里的库中:https://github.com/csuwildcat/SelectorListener
如果要定位各种浏览器,则需要为CSS和animationstart事件名称添加适当的前缀。您可以在上面链接的帖子中阅读更多相关信息。
<强> CSS 强>:
@keyframes nodeInserted {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
div.some-control {
animation-duration: 0.01s;
animation-name: nodeInserted;
}
<强>的JavaScript 强>:
document.addEventListener('animationstart', function(event){
if (event.animationName == 'nodeInserted'){
// Do something here
}
}, true);
这使得Mutation Observers几乎无法做到的事情
<强> CSS 强>:
@keyframes adjacentFocusSequence {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
.one + .two + .three:focus {
animation-duration: 0.01s;
animation-name: adjacentFocusSequence;
}
<强>的JavaScript 强>:
document.addEventListener('animationstart', function(event){
if (event.animationName == 'adjacentFocusSequence'){
// Do something here when '.one + .two + .three' are
// adjacent siblings AND node '.three' is focused
}
}, true);
答案 1 :(得分:11)
@naugtur简要提到的一个新选择是MutationObserver。它被设计为替代已弃用的变异事件,如果您正在开发的浏览器支持它(就像您正在开发浏览器扩展)。
答案 2 :(得分:0)
与描述的csuwldcat相同的技术已被制作成易于使用的jQuery插件(如果这是你的事情):https://github.com/liamdanger/jQuery.DOMNodeAppear
答案 3 :(得分:-1)
这是在这里发布的,因为这个问题是我登陆寻找DOMNodeInserted与IE9失败的帮助的地方,但请注意这个解决方案专门用于在使用End Request功能的ASP.NET上下文中使用jQuery的情况。您的里程可能会有所不同等等....
基本上,我们将完全丢弃DOMNodeInserted并使用End Request来加载我们的事件处理程序:
OLD:
$(document).ready(function() {
$(document).bind('DOMNodeInserted', function(event){
My jQuery event handler...
});
});
===================================
NEW:
function Ajax_EndRequest {
function2();
}
function2 (a,b){
My jQuery event handler...
}
$(document).ready(function(){
add_endRequest(Ajax_EndRequest); //this is what actually invokes the function upon request end.
My jQuery event handler...//REMOVED -- don't need this now
});
答案 4 :(得分:-21)
如果您想要做的只是在DOM更改时触发事件,请执行以下操作:
var nodes=document.getElementsByTagName('*')||document.all;
function domchange(){
alert('Hello');
}
window.setInterval(function(){
var newnodes=document.getElementsByTagName('*')||document.all;
if(newnodes!=nodes){
nodes=newnodes;
domchange();
}
},1);