如何监听 DOM 变化

前言

在MVVM框架中,一是监听数据变化,数据驱动。html

  • 咱们都知道经过Object.defineProperties(),来监听数据的变化,或者使用,代理和反射。
  • 其实在MVVM中,也有操做DOM的场景。那么,咱们是经过哪些API来监听DOM的变化的呢?

当咱们,经过JS操做了DOM以后,咱们须要通知到DOM来更新视图。在VUE中,是维护了一个异步的队列。并非你修改了DOM就会直接更新到视图上面。数组

监听DOM变化的方法:

  • 轮询
  • MutationEvents(基本已废弃)
  • CSS 动画

以上三种都不是很好的方法。那么,咱们今天来介绍一下,如今比较经常使用的:浏览器

  • MutationObserver

咱们选择Mutation Observer

概述

Mutation Observer API 用来监视 DOM 变更。DOM 的任何变更,好比节点的增减、属性的变更、文本内容的变更,这个 API 均可以获得通知。 Mutation Observer 则是异步触发,DOM 的变更并不会立刻触发,而是要等到当前全部 DOM 操做都结束才触发。 这样设计是为了应付 DOM变更频繁的特色。app

举例来讲,若是文档中连续插入1000个li元素,就会连续触发1000个插入事件,执行每一个事件的回调函数,这极可能形成浏览器的卡顿;而 Mutation Observer 彻底不一样,只在 1000 个段落都插入结束后才会触发,并且只触发一次。框架

Mutation Observer有如下特色:

  • 等待全部脚本任务完成后,才会运行,即采用异步方式
  • 把 DOM 变更记录封装成一个数组进行处理,而不是一条条地个别处理 DOM 变更
  • 便可以观察发生在 DOM 节点的全部变更,也能够观察某一类变更

使用

var observe = new MutationObserver(function(mutations, observer){
});
var el = document.querySelector('#app');
var  options = {
  'childList': true,
  'attributes':true
} ;
observer.observe(el, options);
// 建立并返回一个 MutationObserver 实例, 并侦听el元素的变更。
复制代码

小例子

MutationObserver的callback回调函数是异步的,只有在所有DOM操做完成以后才会调用callback。异步

<div id='target' class='block' name='target'>
    target的第一个子节点
    <p>
       <span>target的后代</span>
    </p>
</div>

复制代码
var target=document.getElementById('target');
var i=0
var observe=new MutationObserver(function (mutations,observe) {
    i++   
});
observe.observe(target,{ childList: true});
target.appendChild(docuemnt.createTextNode('1'));
target.appendChild(docuemnt.createTextNode('2'));
target.appendChild(docuemnt.createTextNode('3'));
console.log(i)  //1 callback的回调次数

复制代码

应用

在不少状况下,MutationObserver API 均可以派上用场。例如:函数

  • 你但愿通知 Web 应用程序访问者,他当前所在的页面发生了一些更改。
  • 你正在开发一个新的 JavaScript 框架,须要根据 DOM 的变化动态加载 JavaScript 模块。

总结

  • MutationObserver接口提供了监视对DOM树所作更改的能力。它被设计为旧的Mutation Events功能的替代品,该功能是DOM3 Events规范的一部分。(MDN)
  • DOM MutationObserver,在不影响浏览器性能的状况下响应DOM更改
  • 等待全部脚本任务完成后,才会运行,即采用异步方式
相关文章
相关标签/搜索