Javascript 替代 DOMNodeInserted
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6997826/
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
Alternative to DOMNodeInserted
提问by Fábio
DOMNodeInserted is known to make dynamic pages slow, MDN even recommendsnot using it altogether, but doesn't provide any alternatives.
众所周知,DOMNodeInserted 会使动态页面变慢,MDN 甚至建议不要完全使用它,但不提供任何替代方案。
I'm not interested in the element inserted, I just need to know when some script modifies the DOM. Is there a better alternative to mutation event listeners (maybe getElementsByTagName inside an nsiTimer)?
我对插入的元素不感兴趣,我只需要知道某个脚本何时修改了 DOM。是否有更好的替代突变事件侦听器(可能在 nsiTimer 中使用 getElementsByTagName)?
回答by csuwldcat
If you are creating a web app that targets recent mobile phones and newer versions of browsers (Firefox 5+, Chrome 4+, Safari 4+, iOS Safari 3+, Android 2.1+), you can use the following code to create an awesome event for the insertion of dom nodes, and it even runs on the nodes initially part of the page's static mark-up!
如果您正在创建针对最近的手机和更新版本的浏览器(Firefox 5+、Chrome 4+、Safari 4+、iOS Safari 3+、Android 2.1+)的网络应用程序,您可以使用以下代码创建一个很棒的用于插入 dom 节点的事件,它甚至在最初是页面静态标记的一部分的节点上运行!
Here's the link to the full post with and example: http://www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/
这是完整帖子的链接和示例:http: //www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/
Note on Mutation Observers:while the newer Mutation Observers features in recent browsers are great for monitoring simple insertions and changes to the DOM, do understand that this method can be used to do far more as it allows you to monitor for any CSS rule matchyou can thing of. This is super powerful for many use-cases, so I wrapped this up in a library here: https://github.com/csuwildcat/SelectorListener
关于 Mutation Observers 的注意事项:虽然最近浏览器中较新的 Mutation Observers 功能非常适合监控对 DOM 的简单插入和更改,但请了解此方法可用于执行更多操作,因为它允许您监控与您匹配的任何 CSS 规则可以的东西。这对于许多用例来说都非常强大,所以我将它封装在一个库中:https: //github.com/csuwildcat/SelectorListener
You'll need to add the appropriate prefixes to the CSS and animationstart event name if you want to target various browsers. You can read more about that in the post linked to above.
如果您想针对各种浏览器,您需要为 CSS 和 animationstart 事件名称添加适当的前缀。您可以在上面链接的帖子中阅读更多相关信息。
The basic node insertion case
基本节点插入案例
CSS:
CSS:
@keyframes nodeInserted {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
div.some-control {
animation-duration: 0.01s;
animation-name: nodeInserted;
}
JavaScript:
JavaScript:
document.addEventListener('animationstart', function(event){
if (event.animationName == 'nodeInserted'){
// Do something here
}
}, true);
Listening for more complex selector matches:
侦听更复杂的选择器匹配:
This enables things that are almost impossible to do with Mutation Observers
这使得 Mutation Observers 几乎不可能做到的事情成为可能
CSS:
CSS:
@keyframes adjacentFocusSequence {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
.one + .two + .three:focus {
animation-duration: 0.01s;
animation-name: adjacentFocusSequence;
}
JavaScript:
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);
回答by Mike Henry
One new alternative that @naugtur briefly mentioned is MutationObserver. It's designed as a replacement for the deprecated mutation events, if the browser(s) you're developing for supports it (like if you're developing a browser extension).
@naugtur 简要提到的一种新选择是MutationObserver。如果您正在开发的浏览器支持它(例如,如果您正在开发浏览器扩展),它被设计为已弃用的突变事件的替代品。
回答by Arktype
The same technique as csuwldcat described has been made into an easy to use jQuery plugin (if that's your thing): https://github.com/liamdanger/jQuery.DOMNodeAppear
与 csuwldcat 描述的相同的技术已被制作成一个易于使用的 jQuery 插件(如果这是你的东西):https: //github.com/liamdanger/jQuery.DOMNodeAppear
回答by ColdSharper
This is posted here because this question is where I landed looking for help with DOMNodeInserted failing with IE9, but please note this solution is specifically for a situation where jQuery is being used within an ASP.NET context that uses an End Request function. Your mileage may vary, etc....
这是张贴在这里,因为这个问题是我在 DOMNodeInserted 与 IE9 失败的情况下寻求帮助的地方,但请注意,此解决方案专门用于在使用 End Request 函数的 ASP.NET 上下文中使用 jQuery 的情况。您的里程可能会有所不同,等等......
Basically, we are going to throw away the DOMNodeInserted altogether and use End Request to load our event handler:
基本上,我们将完全丢弃 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
});
回答by Anonymous
If all you want to do is trigger an event when the DOM changes, do something like this:
如果您只想在 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);