资讯专栏INFORMATION COLUMN

JavaScript工作原理(九):使用MutationObserver跟踪DOM的改变

1fe1se / 1047人阅读

摘要:概观是现代浏览器提供的,用于检测中的变化。您可能正在使用所见即所得的编辑器,试图实现撤销重做功能。函数的第一个参数是在一个批次中发生的所有改变的集合。虽然有用,但中的每一次更改都会触发突变事件,这又会导致性能问题。


Web应用程序在客户端越来越重要,原因很多,比如需要更丰富的用户界面来容纳更复杂的应用程序必须提供的功能,实时计算等等。

复杂性的增加使得在Web应用程序的生命周期中的每个特定时刻都很难知道UI的确切状态。

如果你正在构建某种框架或仅仅是一个库,这会变得更加困难,例如,它必须作出反应并执行某些依赖于DOM的操作。

概观

MutationObserver是现代浏览器提供的Web API,用于检测DOM中的变化。使用此API,可以侦听新添加或删除的节点,属性更改或文本节点文本内容的更改。

你为什么想这么做?

MutationObserver API在很多情况下可以非常方便地使用。例如:

您希望通知您的网络应用访问者在他当前所在的页面上发生了一些变化。

您正在研究一种新的花式JavaScript框架,该框架可根据DOM如何变化来动态加载JavaScript模块。

您可能正在使用所见即所得的编辑器,试图实现撤销/重做功能。通过利用MutationObserver API,你可以在任何时候都能很容易undo他们

这些只是MutationObserver如何提供帮助的几个例子。

如何使用MutationObserver

在你的应用中实现MutationObserver相当容易。您需要通过传递一个函数来创建一个MutationObserver实例,该函数在每次发生突变时都会被调用。函数的第一个参数是在一个批次中发生的所有改变的集合。每个改变都提供有关其类型和已发生变化的信息。
MutationObserver API,您可以在任何给定的位置知道进行了哪些更改,因此您可以轻松地撤消它们。

var mutationObserver = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    console.log(mutation);
  });
});

创建的对象有三个方法:

observe - 开始倾听变化。需要两个参数 - 您要观察的DOM节点和一个设置对象

disconnect - 停止监听更改

takeRecords - 在回调被触发前返回最后一批更改。

以下片段显示了如何开始观察:

// Starts listening for changes in the root HTML element of the page.
mutationObserver.observe(document.documentElement, {
  attributes: true,
  characterData: true,
  childList: true,
  subtree: true,
  attributeOldValue: true,
  characterDataOldValue: true
});

现在假设你有一些简单的DIV在DOM中:

Simple div

使用jQuery,你你可以移除div的class属性:

$("#sample-div").removeAttr("class");

正如我们开始观察的那样,在调用mutationObserver.observe(...)之后,我们将在相应的MutationRecord的控制台中看到一个日志:

这是由删除class属性引起的变异。

最后,为了在完成后停止观察DOM,可以执行以下操作:

// Stops the MutationObserver from listening for changes.
mutationObserver.disconnect();

如今,MutationObserver得到了广泛的支持:

备择方案

然而,MutationObserver并不总是可用的。那么在MutationObserver出现之前开发者会采取什么措施呢?

还有其他几个选项可用:

轮询

MutationEvents

CSS动画

轮询

最简单和最简单的方式是通过轮询。使用浏览器setInterval WebAPI,您可以设置一个任务,定期检查是否发生了任何更改。当然,这种方法会显着降低网络应用程序/网站的性能。

MutationEvents

在2000年,引入了MutationEvents API。虽然有用,但DOM中的每一次更改都会触发突变事件,这又会导致性能问题。现在,MutationEvents API已被弃用,很快,现代浏览器将不再支持它。

这是MutationEvents的浏览器支持:

CSS动画

一个有点奇怪的选择是依赖CSS动画。这听起来有点混乱。基本上,这个想法是创建一个动画,一旦一个元素被添加到DOM就会触发该动画。动画开始的那一刻,animationstart事件将被触发:如果您已将事件处理程序附加到该事件,则您将确切知道元素何时添加到DOM。 动画的执行时间应该很小,以至于用户几乎看不到它。

首先,我们需要一个父元素,在其中我们想要听节点插入:

为了获得节点插入的句柄,我们需要设置一系列关键帧动画,这些动画将在插入节点时开始:

@keyframes nodeInserted { 
 from { opacity: 0.99; }
 to { opacity: 1; } 
}

在创建关键帧后,需要将动画应用到您想要的元素上。请注意,持续时间较短 - 他们正在放松浏览器中的动画脚印:

#container-element * {
 animation-duration: 0.001s;
 animation-name: nodeInserted;
}

这将动画添加到容器元素的所有子节点。当动画结束时,插入事件将触发。

我们需要一个JavaScript函数作为事件监听器。在该函数中,必须进行初始event.animationName检查以确保它是我们想要的动画。

var insertionListener = function(event) {
  // Making sure that this is the animation we want.
  if (event.animationName === "nodeInserted") {
    console.log("Node has been inserted: " + event.target);
  }
}

显示是时候添加监听器到父容器了:

document.addEventListener(“animationstart”, insertionListener, false); // standard + firefox
document.addEventListener(“MSAnimationStart”, insertionListener, false); // IE
document.addEventListener(“webkitAnimationStart”, insertionListener, false); // Chrome + Safari

CSS动画的浏览器支持:

与上述解决方案相比,MutationObserver具有许多优点。 从本质上讲,它涵盖了DOM中可能发生的每一个变化,并且它在批处理中引发更改时更加优化。最重要的是,所有主要的现代浏览器都支持MutationObserver,以及一些使用MutationEvents的polyfill。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94731.html

相关文章

  • JavaScript是如何工作:使用 MutationObserver 跟踪 DOM 变化

    摘要:复杂性的增加使得在应用程序生命周期的每个给定时刻都很难知道的确切状态。概述用来监视变动。这个被创建的对象有三个方法启动监听用来停止观察返用来清除变动记录,即不再处理未处理的变动。使用浏览器方法,可以设置一个任务,定期检查是否发生了任何更改。 这是专门探索 JavaScript 及其所构建的组件的系列文章的第10篇。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! ...

    jasperyang 评论0 收藏0
  • JavaScript 工作原理之十-使用 MutationObserver 监测 DOM 变化

    摘要:概述是现代浏览器提供的用来检测变化的网页接口。比如通知用户当前所在的页面所发生的一些变化。触发回调前返回最新的批量变化。在函数内部,开始必须使用代码进行检查,确保是我们所监听的动画。 原文请查阅这里,略有删减,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland。 本系列持续更新中,Github 地址请查阅这里。 这是 JavaScript 工作原理的第十章。 网络应用...

    bbbbbb 评论0 收藏0
  • JavaScript 工作原理之十-使用 MutationObserver 监测 DOM 变化

    摘要:概述是现代浏览器提供的用来检测变化的网页接口。比如通知用户当前所在的页面所发生的一些变化。触发回调前返回最新的批量变化。在函数内部,开始必须使用代码进行检查,确保是我们所监听的动画。 原文请查阅这里,略有删减,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland。 本系列持续更新中,Github 地址请查阅这里。 这是 JavaScript 工作原理的第十章。 网络应用...

    zone 评论0 收藏0
  • JavaScript 工作原理之十-使用 MutationObserver 监测 DOM 变化

    摘要:概述是现代浏览器提供的用来检测变化的网页接口。比如通知用户当前所在的页面所发生的一些变化。触发回调前返回最新的批量变化。在函数内部,开始必须使用代码进行检查,确保是我们所监听的动画。 原文请查阅这里,略有删减,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland。 本系列持续更新中,Github 地址请查阅这里。 这是 JavaScript 工作原理的第十章。 网络应用...

    Richard_Gao 评论0 收藏0
  • JavaScript 是如何工作系列文章已更新到22篇

    摘要:为了方便大家共同学习,整理了之前博客系列的文章,目前已整理是如何工作这个系列,可以请猛戳博客查看。以下列出该系列目录,欢迎点个星星,我将更友动力整理理优质的文章,一起学习。 为了方便大家共同学习,整理了之前博客系列的文章,目前已整理 JavaScript 是如何工作这个系列,可以请猛戳GitHub博客查看。 以下列出该系列目录,欢迎点个星星,我将更友动力整理理优质的文章,一起学习。 J...

    lx1036 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<