Javascript 检测/监控 DOM 更改的最有效方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2457043/
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
Most efficient method of detecting/monitoring DOM changes?
提问by Graza
I need an efficient mechanism for detecting changes to the DOM. Preferably cross-browser, but if there's any efficient means which are notcross browser, I can implement these with a fail-safe cross browser method.
我需要一种有效的机制来检测 DOM 的变化。最好是跨浏览器,但如果有任何不是跨浏览器的有效方法,我可以使用故障安全的跨浏览器方法来实现这些。
In particular, I need to detect changes that would affect the text on a page, so any new, removed or modified elements, or changes to inner text (innerHTML) would be required.
特别是,我需要检测会影响页面上文本的更改,因此需要任何新的、删除的或修改的元素,或者对内部文本 (innerHTML) 的更改。
I don't have control over the changes being made (they could be due to 3rd party javascript includes, etc), so it can't be approached from this angle - I need to "monitor" for changes somehow.
我无法控制所做的更改(它们可能是由于 3rd 方 javascript 包含等),因此无法从这个角度进行处理 - 我需要以某种方式“监视”更改。
Currently I've implemented a "quick'n'dirty" method which checks body.innerHTML.lengthat intervals. This won't of course detect changes which result in the same length being returned, but in this case is "good enough" - the chances of this happening are extremely slim, and in this project, failing to detect a change won't result in lost data.
目前我已经实现了一个“quick'n'dirty”的方法,它body.innerHTML.length每隔一段时间检查一次。这当然不会检测到导致返回相同长度的更改,但在这种情况下“足够好” - 这种情况发生的可能性非常小,并且在这个项目中,无法检测到更改将不会导致在丢失的数据中。
The problem with body.innerHTML.lengthis that it's expensive. It can take between 1 and 5 milliseconds on a fastbrowser, and this can bog things down a lot - I'm also dealing with a large-ish number of iframes and it all adds up. I'm pretty sure the expensiveness of doing this is because the innerHTML text is not stored statically by browsers, and needs to be calculated from the DOM every time it is read.
问题body.innerHTML.length是它很贵。在快速浏览器上可能需要 1 到 5 毫秒,这可能会使事情陷入困境 - 我也在处理大量的 iframe,这一切都加起来了。我很确定这样做的代价是因为innerHTML 文本不是由浏览器静态存储的,每次读取时都需要从DOM 计算。
The types of answers I am looking for are anything from the "precise" (for example event) to the "good enough" - perhaps something as "quick'n'dirty" as the innerHTML.length method, but that executes faster.
我正在寻找的答案类型是从“精确”(例如事件)到“足够好”的任何东西 - 也许像 innerHTML.length 方法一样“快速”和“肮脏”,但执行速度更快。
EDIT: I should also point out that whilst it would be "nice" to detect the precise element that has been modified, it is not an absolute necessity - just the fact that there has been anychange would be good enough. Hopefully this broadens people's responses. I'm going to investigate Mutation Events, but I still need a fallback for IE support, so any whacky, creative, outside-of-the-square ideas would be very welcome.
编辑:我还应该指出,虽然检测已修改的精确元素会“很好”,但这并不是绝对必要的——只要有任何变化就足够了。希望这能扩大人们的反应。我将调查 Mutation Events,但我仍然需要对 IE 支持的后备,所以任何古怪的、有创意的、不合时宜的想法都会受到欢迎。
采纳答案by jagamot
http://www.quirksmode.org/js/events/DOMtree.html
http://www.quirksmode.org/js/events/DOMtree.html
jQuery now supports a way to attach events to existing and future elements corresponding to a selector: http://docs.jquery.com/Events/live#typefn
jQuery 现在支持一种将事件附加到与选择器对应的现有和未来元素的方法:http: //docs.jquery.com/Events/live#typefn
Another interesting find - http://james.padolsey.com/javascript/monitoring-dom-properties/
另一个有趣的发现 - http://james.padolsey.com/javascript/monitoring-dom-properties/
回答by zeveck
To bring this up to date, the DOM4 standard does away with Mutation Events and replaces them with Mutation Observers: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
为了更新这一点,DOM4 标准取消了 Mutation Events 并用 Mutation Observers 取而代之:https: //developer.mozilla.org/en-US/docs/Web/API/MutationObserver
回答by Gabriele Petrioli
Mutation eventsare the W3 recommendation of what you are looking for..
突变事件是您正在寻找的 W3 推荐。
Not sure if they are supported all around.. (IE will most likely not support them..)
不确定它们是否得到全面支持..(IE 很可能不支持它们..)
回答by Chibu
You could try using the DOMNodeInserted and DOMNodeRemoved events. Acording to Quirksmode, they kind of work in most browsers, with the notable exception of IE...
您可以尝试使用 DOMNodeInserted 和 DOMNodeRemoved 事件。根据 Quirksmode,它们可以在大多数浏览器中工作,但 IE 除外……
回答by pie6k
I have recently written a plugin that does exactly that - jquery.initialize
我最近写了一个插件就是这样做的 - jquery.initialize
You use it the same way as .eachfunction
您可以像使用.each函数一样使用它
$(".some-element").initialize( function(){
$(this).css("color", "blue");
});
The difference from .eachis - it takes your selector, in this case .some-elementand wait for new elements with this selector in the future, if such element will be added, it will be initialized too.
与此不同的.each是 - 它需要您的选择器,在这种情况下,.some-element并在将来等待具有此选择器的新元素,如果将添加此类元素,它也将被初始化。
In our case initialize function just change element color to blue. So if we'll add new element (no matter if with ajax or even F12 inspector or anything) like:
在我们的例子中,初始化函数只是将元素颜色更改为蓝色。因此,如果我们要添加新元素(无论是使用 ajax 还是 F12 检查器或其他任何东西),例如:
$("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color!
Plugin will init it instantly. Also plugin makes sure one element is initialized only once. So if you add element, then .deatch()it from body and then add it again, it will not be initialized again.
插件会立即初始化它。插件还确保一个元素只初始化一次。因此,如果您添加元素,然后将.deatch()其从主体中添加,然后再次添加,则不会再次初始化。
$("<div/>").addClass('some-element').appendTo("body").detach()
.appendTo(".some-container");
//initialized only once
Plugin is based on MutationObserver- it will work on IE9 and 10 with dependencies as detailed on the readme page.
插件基于MutationObserver- 它将在 IE9 和 10 上工作,依赖项详见自述页面。
回答by Val
jQuery Mutatedoes this too, by default it supports like height, width, scrollHeightetc... but it also can be extended with a little bit of extra code to add new events like see if text has changed etc...
jQuery Mutate也这样做,默认情况下它支持像height, width, scrollHeight等......但它也可以用一些额外的代码进行扩展以添加新事件,例如查看文本是否已更改等......
http://www.jqui.net/jquery-projects/jquery-mutate-official/
http://www.jqui.net/jquery-projects/jquery-mutate-official/
Hope it helps
希望能帮助到你

