JavaScript works of ten - Use MutationObserver Monitoring DOM changes

Please refer to the original here , a little cut, this article uses the Creative Commons Attribution 4.0 International License Agreement for sharing, BY Troland .

Continuously updated in this series, Github address check here .

This is the tenth chapter JavaScript works.

Network applications on the client increasingly complex, which is caused by a number of factors, such as the need richer interactive interface to provide a more sophisticated application functions, real-time computing.

Increasingly complex network applications can not know the cause of their life cycle in a given moment the exact interface state.

If you're building some framework or a library, it will be more difficult, for example, you can not respond and perform certain operations by monitoring the DOM.

Outline

MutationObserver  modern browser provides a web interface is used to detect changes in DOM. You can use this interface to listen add or delete nodes, change attributes, or content of the text node changes.

Diansha can do good?

You can come in handy MutationObserver interfaces in the following situations. such as:

  • Notice some changes in the page where the user is currently happening.
  • By using some great JavaScript framework based on changes in the DOM JavaScript to dynamically load modules.
  • Possible when you are developing a WYSIWYG editor when using MutationObserver interface to gather change at any point of time, making it easy to implement undo / redo functionality.

It's just a few MutationObserver usage scenarios.

How to use MutationObserver

MutationObserver integrated in the application is fairly simple. To constructor by MutationObserverthe function called when a change occurs in each occurrence DOM passed as a parameter to a function to initialize a MutationObserver instance. MutationObserverThe first argument is the DOM variation set of single batch. Each change contains the type of change and the changes that occurred.

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

Examples of objects created with three methods:

  • observe- start listening. It takes two parameters - DOM node to be observed, and a configuration object.
  • disconnect- Stop listening change.
  • takeRecords- Returns the latest batch DOM changes before the trigger callback.

The following code snippet to start listening:

// 开始监听页面根元素 HTML 变化。
mutationObserver.observe(document.documentElement, {
  attributes: true,
  characterData: true,
  childList: true,
  subtree: true,
  attributeOldValue: true,
  characterDataOldValue: true
});

Now, suppose you write a simple divelement:

<div id="sample-div" class="test"> Simple div </div>

You can use jQuery to remove the div classattribute:

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

When you call mutationObserver.observe(…)you can start listening DOM changes.

When each DOM changes, it will print each MutationRecord log information:

This change was made to remove classproperty caused.

Finally, if you want to stop listening DOM change you can use the following method:

// MutationObserver 停止监听 DOM 变化
mutationObserver.disconnect();

Now, MutationObserverthe browser is compatible with good conditions:

alternative method

However, before MutationObserverand not widely used. Then, when there is no MutationObservertime, the developer is how to solve the listener DOM to change it?

There are a few methods available:

  • polling
  • MutationEvents
  • CSS animation

polling

The simplest method that the use of coarse and polling. Using the browser's built-in web-setInterval you can create a scheduled task to regularly check changes in the DOM. Of course, this method significantly reduced the performance of network applications / websites.

其实,这是可以理解为脏检查,如果有使用过 AngularJS 应该会有看过其脏检查所导致的性能问题。在我的另一个系列里面有稍微介绍了下,具体可以查看这里

MutationEvents

早在 2000 年,就推出了 MutationEvents API 。虽然挺管用的,但是每个单一的 DOM 变化都会触发 mutation 事件,结果又会造成性能问题。现在,MutationEvents 接口已经被废弃,不久的将来,现代浏览器全都将停止支持该接口。

以下是 MutationEvents 的浏览器兼容情况:

CSS 动画

依靠 CSS 动画 是一个有点令人感到新奇的替代方案。这听起来会让人有些困惑。大体上,实现思路是这样的,创建一个动画,一旦在 DOM 中添加一个元素就会触发该动画。开始执行 CSS 动画的时候就会触发 animationstart 事件:假设为该事件添加事件监听器,就可以准确知晓 DOM 中添加元素的时机。动画的运行时间周期必须非常的短以便让用户感知不到,即体验更佳。

首先,需要一个父级元素,在里面监听节点添加事件:

<div id=”container-element”></div>

为了处理节点的添加,需要创建关键帧序列动画,该序动画在添加节点的时候启动:

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

创建好关键帧之后,在需要监听的元素上应用动画。注意到那个短暂的持续时间-在浏览器端动画痕迹会非常平滑(即用户会感觉不到有动画发生):

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

这样会为 container-element 的所有后代节点添加动画。当动画结束,触发 insertion 事件。

我们需要创建一个函数作为事件监听器。在函数内部,开始必须使用 event.animationName 代码进行检查,确保是我们所监听的动画。

var insertionListener = function(event) {
  // 确保是所监听的动画
  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 可能发生的每个变化并且性能更优,因其会批量 DOM 变化之后才触发回调事件。总之,MutationObserver 的兼容性很好,并且还有一些垫片,这些垫片底层是基于 MutationEvents 的。

本系列持续更新中,Github 地址请查阅这里

Guess you like

Origin www.cnblogs.com/jlfw/p/11912514.html