Javascript 域节点插入的替代方案
众所周知,DOMNodeInserted会使动态页面变慢,而不是完全使用它,但它不提供任何替代方案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(
我对插入的元素不感兴趣,我只需要知道一些脚本何时修改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我已经用另一个用例更新了我的答案,这清楚地说明了这种方法可以轻松完成突变观察者无法做到的事情。