Javascript 域节点插入的替代方案

Javascript 域节点插入的替代方案,javascript,dom,firefox-addon,dhtml,mutation-events,Javascript,Dom,Firefox Addon,Dhtml,Mutation Events,众所周知,DOMNodeInserted会使动态页面变慢,而不是完全使用它,但它不提供任何替代方案 我对插入的元素不感兴趣,我只需要知道一些脚本何时修改DOM。是否有更好的替代突变事件监听器(可能是nsiTimer中的getElementsByTagName)?如果您只想在DOM更改时触发事件,请执行以下操作: var nodes=document.getElementsByTagName('*')||document.all; function domchange(){ alert(

众所周知,DOMNodeInserted会使动态页面变慢,而不是完全使用它,但它不提供任何替代方案


我对插入的元素不感兴趣,我只需要知道一些脚本何时修改DOM。是否有更好的替代突变事件监听器(可能是nsiTimer中的getElementsByTagName)?

如果您只想在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);

如果您正在创建一个针对最新手机和更新版本浏览器(Firefox 5+、Chrome 4+、Safari 4+、iOS Safari 3+、Android 2.1+)的web应用程序,您可以使用以下代码创建一个插入dom节点的精彩事件,它甚至可以在页面静态标记的最初部分的节点上运行

以下是完整文章的链接和示例:

关于变异观察者的注意事项:虽然最近浏览器中较新的变异观察者功能非常适合监视对DOM的简单插入和更改,但请务必理解,这种方法可以用于做更多的事情,因为它允许您监视任何CSS规则匹配。这对于许多用例来说都是非常强大的,所以我在这里将其打包到了一个库中:

如果要针对各种浏览器,则需要在CSS和animationstart事件名称中添加适当的前缀。你可以在上面链接的帖子中了解更多

基本节点插入情况 CSS

@keyframes nodeInserted {  
    from {  
        outline-color: #fff; 
    }
    to {  
        outline-color: #000;
    }  
}

div.some-control {
    animation-duration: 0.01s;
    animation-name: nodeInserted;
}
document.addEventListener('animationstart', function(event){
    if (event.animationName == 'nodeInserted'){
        // Do something here
    }
}, true);
@keyframes adjacentFocusSequence {  
    from {  
        outline-color: #fff; 
    }
    to {  
        outline-color: #000;
    }  
}

.one + .two + .three:focus {
    animation-duration: 0.01s;
    animation-name: adjacentFocusSequence;
}
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);
JavaScript

@keyframes nodeInserted {  
    from {  
        outline-color: #fff; 
    }
    to {  
        outline-color: #000;
    }  
}

div.some-control {
    animation-duration: 0.01s;
    animation-name: nodeInserted;
}
document.addEventListener('animationstart', function(event){
    if (event.animationName == 'nodeInserted'){
        // Do something here
    }
}, true);
@keyframes adjacentFocusSequence {  
    from {  
        outline-color: #fff; 
    }
    to {  
        outline-color: #000;
    }  
}

.one + .two + .three:focus {
    animation-duration: 0.01s;
    animation-name: adjacentFocusSequence;
}
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);
正在侦听更复杂的选择器匹配: 这使得突变观察者几乎不可能做到的事情得以实现

CSS

@keyframes nodeInserted {  
    from {  
        outline-color: #fff; 
    }
    to {  
        outline-color: #000;
    }  
}

div.some-control {
    animation-duration: 0.01s;
    animation-name: nodeInserted;
}
document.addEventListener('animationstart', function(event){
    if (event.animationName == 'nodeInserted'){
        // Do something here
    }
}, true);
@keyframes adjacentFocusSequence {  
    from {  
        outline-color: #fff; 
    }
    to {  
        outline-color: #000;
    }  
}

.one + .two + .three:focus {
    animation-duration: 0.01s;
    animation-name: adjacentFocusSequence;
}
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);
JavaScript

@keyframes nodeInserted {  
    from {  
        outline-color: #fff; 
    }
    to {  
        outline-color: #000;
    }  
}

div.some-control {
    animation-duration: 0.01s;
    animation-name: nodeInserted;
}
document.addEventListener('animationstart', function(event){
    if (event.animationName == 'nodeInserted'){
        // Do something here
    }
}, true);
@keyframes adjacentFocusSequence {  
    from {  
        outline-color: #fff; 
    }
    to {  
        outline-color: #000;
    }  
}

.one + .two + .three:focus {
    animation-duration: 0.01s;
    animation-name: adjacentFocusSequence;
}
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);

之所以在这里发布这个问题,是因为这个问题是我在IE9失败的DomainDeInserted中寻求帮助的地方,但请注意,这个解决方案特别适用于使用End Request函数的ASP.NET上下文中使用jQuery的情况。您的里程可能会有所不同,等等

基本上,我们将完全抛弃DOMNodeInserted,并使用End Request加载事件处理程序:

旧的:

===================================

新的:



@naugtur简要提到的一个新选择是。如果您正在开发的浏览器支持它(就像您正在开发一个浏览器扩展),那么它被设计为替换不推荐的变异事件。

与csuwldcat描述的相同技术已经被制作成一个易于使用的jQuery插件(如果这是您的事情):

您需要整个DOM的该功能吗?在任何时候?如果你有一个特定的脚本并且你知道它是如何工作的,你可以“诱杀”它使用的DOM方法/属性。否则你就倒霉了,监视所有DOM修改正是使突变事件变慢的原因。Šime Vidas,是的,我做了,一些脚本在用户与页面交互时插入标记。@Fabio这些脚本是第三方还是你的脚本?第三方。我有一个扩展可以跟踪网页中的内容。这是一个可怕的代码,它会屠杀插入的任何网页。这不是真的,但评论很棒。如果你愿意的话,你可以把最后一个小“1”改成500。这将每半秒更新一次,而不是每秒(最多)1000次。请访问msnbc.com这样的大型网站,并注意
getElementsByTagName(“*”)
集合的大小。我有“2605”元素。你不会真的认为这是个好主意。哈哈哈,我只是不得不登录来为你们鼓掌。。。这些评论确实是纯金的。是的,单单CSS中的
*
操作符就很昂贵。请不要再添加
警报(…)
。还有1ms民意测验,天哪!这是迄今为止我所见过的
DOMNodeInserted
最优秀的替代方案。事实上,我已经使用它好几个月了,而且效果很好。该技术可以应用于IE10+,但
clip:rect
在IE10中不起作用(不确定11)。我在我的
insertionQuery
lib@naugtur outline中使用了
outline
,这是一个好主意,特别是如果你可以只在颜色上做虚拟动画。我可能会用它来更新这个帖子和我的博客文章。@naugtur现在在Github上更新了它,我已经调整了这个答案以匹配它-谢谢提醒!很抱歉这么说,但现在你只是把人们弄糊涂了。你文章中的代码远远不是跨浏览器的(动画事件有前缀,动画本身需要其他前缀),我从来没有说过你可以只设置颜色的动画。这不是我所测试的。但是,突变观察员不提供基于CSS选择器的突变通知,这是一个非常有用的特性。我有一个小模块,它封装了上面的关键帧解决方案,使CSS选择器的列表更加容易:Think@csuwldcat的建议已经过时了–变异观察者可以检测到您可能从CSS选择器推断出的结果(使用
属性
),等等(节点删除、文本节点更改)@Barney有两件事:1)你可以用这种方法监听选择器匹配,这在变异观察器中是不可能的-有关它提供的更多信息,请参见:,2)变异观察器在IE9、Safari 5、6等旧浏览器中不受支持,等等。@Barney我已经用另一个用例更新了我的答案,这清楚地说明了这种方法可以轻松完成突变观察者无法做到的事情。