最有效的检测/监控DOM变化的方法?

时间:2010-03-16 18:26:52

标签: javascript dom mutation-events mutation-observers

我需要一种有效的机制来检测DOM的变化。最好是跨浏览器,但如果有任何有效的方式跨浏览器,我可以使用故障安全的跨浏览器方法实现这些。

特别是,我需要检测会影响页面上文本的更改,因此需要任何新的,删除或修改的元素或对内部文本(innerHTML)的更改。

我无法控制正在进行的更改(可能是由于第三方javascript包含等),因此无法从这个角度进行处理 - 我需要以某种方式“监控”更改。< / p>

目前我已经实施了一个“quick'n'dirty”方法,每隔一段时间检查一次body.innerHTML.length。这当然不会检测导致返回相同长度的变化,但在这种情况下“足够好” - 这种情况发生的可能性非常小,并且在此项目中,未能检测到更改将不会导致数据丢失。

body.innerHTML.length的问题在于它很昂贵。在 fast 浏览器上可能需要1到5毫秒的时间,这可能会让事情陷入困境 - 我也在处理大量的iframe,而且这些都加起来了。我很确定这样做的代价是昂贵的,因为innerHTML文本不是由浏览器静态存储的,每次读取时都需要从DOM计算。

我正在寻找的答案类型是从“精确”(例如事件)到“足够好”的任何东西 - 也许就像innerHTML.length方法一样“quick'n'dirty”,但执行更快。

编辑: 我还应该指出,虽然检测已经修改过的精确元素会“很好”,但这并不是绝对必要的 - 只是事实上任何变化都足够好了。希望这能够扩大人们的反应。我将调查突变事件,但我仍然需要IE支持的后备,所以任何笨拙,有创意,非常方便的想法都会非常受欢迎。

6 个答案:

答案 0 :(得分:31)

为了更新这一点,DOM4标准取消了Mutation Events并将其替换为Mutation Observers:https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

答案 1 :(得分:10)

http://www.quirksmode.org/js/events/DOMtree.html

jQuery现在支持将事件附加到与选择器对应的现有和未来元素的方法:http://docs.jquery.com/Events/live#typefn

另一个有趣的发现 - http://james.padolsey.com/javascript/monitoring-dom-properties/

答案 2 :(得分:8)

Mutation events是您正在寻找的W3建议..

不确定它们是否全部受到支持..(IE很可能不支持它们。)

答案 3 :(得分:1)

您可以尝试使用DOMNodeInserted和DOMNodeRemoved事件。根据Quirksmode,它们在大多数浏览器中都有用,除了IE ...

http://www.quirksmode.org/dom/events/index.html

答案 4 :(得分:1)

我最近编写了一个插件,它正是这样做的 - jquery.initialize

您使用与.each功能

相同的方式
$(".some-element").initialize( function(){
    $(this).css("color", "blue"); 
});

.each的区别在于 - 它需要你的选择器,在这种情况下为.some-element并且等待将来使用此选择器的新元素,如果添加这样的元素,它也将被初始化

在我们的案例中,初始化函数只是将元素颜色更改为蓝色。因此,如果我们要添加新元素(无论是使用ajax还是F12检查员或其他任何东西),例如:

$("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color!

插件会立即启动它。插件也确保一个元素只初始化一次。因此,如果您添加元素,然后.deatch()从主体添加它,然后再次添加它,它将不会再次初始化。

$("<div/>").addClass('some-element').appendTo("body").detach()
    .appendTo(".some-container");
//initialized only once

插件基于MutationObserver - 它可以在IE9和10上使用依赖关系,详见readme page

答案 5 :(得分:0)

jQuery Mutate 也是这样做的,默认情况下它支持height, width, scrollHeight等...但它也可以通过一些额外的代码来扩展以添加新事件比如看文字是否有变化等......

http://www.jqui.net/jquery-projects/jquery-mutate-official/

希望有所帮助