对 DOM 中的变化做出反应:Mutation Observers、window.addEventListener("onresize"、回调)或 CSS 替代方案?

Reacting to changes in the DOM: Mutation Observers, window.addEventListener("onresize", callback) or CSS alternatives?

我正在尝试找出对 DOM 中的变化做出反应的最佳方式。

我读过类似的帖子,例如 one and this one and neither of them make it explicitly clear when to use Mutation Observers and when to use window.addEventListener("onresize", callback). Are Mutation Observers more efficient than window.addEventListener("onresize", callback) even if the resize event is throttled?

我将其包含在 CSS3 标签下,因为它看起来像是在 2012 年 some neat CSS tricks that triggered custom resize events,我想知道从那以后是否有任何创新。

这两个是解决不同问题的不同工具。变异观察者用于对 DOM 中的变化做出反应。假设您想编写一个 javascript 函数,将整个页面上的一个词替换为另一个词,而最终用户不会注意到任何事情。您可以在此处使用 setInterval,但是从服务器(或异步 AJAX 调用)加载内容时存在 "flashing" 内容的风险,除非您将间隔设置为非常小的值,在这种情况下它会变成一个非常耗费资源的解决方案。

因此,您可以编写一个变异观察器,每次 DOM 发生变化时都会调用它,其中包括页面呈现或 javascript adding/removing/modifying HTML 行中的元素。我曾经编写的一个客户端 A/B 测试工具使用这些工具来捕获 DOM 中的变化并以最快的方式处理它们。

将侦听器添加到 onresize 事件就是这样做的 - 它会在浏览器 window 调整大小时被调用,无论此时的 DOM 状态如何。所以这两个不能真正互换。 Mutation observers 可以在较重的页面上获得相当 "expensive" 的资源明智,因此您可能必须在那里实施限制。您需要什么取决于您正在处理的具体情况,无法肯定地回答。

除了处理两个完全不同且通常不相关的任务外,它们的时间也不同。

MutationObserver 回调在当前事件期间作为 microtask 执行,此时屏幕上尚未绘制任何更改。由于 Javascript 是单线程的,回调执行会阻塞进一步的 DOM 解析和整个 JS 引擎,所以你希望让它变得非常快(恐怕大多数包装库都没有,因为它们的多功能性)并避免在加载复杂页面时观察整个 document,因为回调可能会被调用数百次,每个突变中都有很多 addedNodes。

事件(包括"resize"事件)被添加到内部事件队列,并在当前事件队列已完全处理并绘制更改时进行处理。例如,setTimeout(callback, 0) 创建一个普通的 事件任务 ,可能会在复杂页面加载期间将回调执行延迟 100-1000 毫秒。

因此,只有当您真的想在绘制之前更改某些内容以使您的更改与页面无缝集成时,才使用 MutationObserver。当然,MutationObserver 只会在实际 html 属性值或节点 added/removed/changed 发生变化时捕获变化,而不仅仅是基于 CSS 规则计算出的宽度。