美文网首页让前端飞Web前端之路
你所不知道的MutationObserver

你所不知道的MutationObserver

作者: 相遇一头猪 | 来源:发表于2019-08-20 23:53 被阅读0次

    简介

    MutationObserver是html5的api,功能就是用来监听dom的变动,有点类似事件监听。
    MutationObserver与事件监听本质上的不同是事件触发是同步,而MutationObserver会等待当前所有dom操作完成后再触发。

    用法

    MutationObserver是一个构造函数,接受一个用来处理节点变化的回调函数作为参数,如下:

    var observer = new MutationObserver(function(mutations) {
          //dosomething    
    })
    

    函数的第一个参数是dom变动数组,每个元素都记录了它的类型和发生变化的信息。

    创建的对象有三个方法:

    • observe 启动监听
    • disconnect 结束监听
    • takeRecords 清空记录队列并返回里面的内容

    observe

    observe方法用来启动监听,它接受两个参数,target:需要观察目标,options:通过对象成员来设置观察选项(属性、子dom、文本等)

    options有以下几个选项:

    • childList : 表示观察目标子节点的变化,比如添加或者删除子节点,不包括修改以及子节点后代的变化。
    • attributes :观察属性的变化。
    • characterData: 观察数据的改变。
    • subtree: 观察目标及后代的改变。
    • attributeOldValue:如果属性为true或者省略,则相当于设置为true,表示需要记录改变前的目标属性值,设置了attributeOldValue可以省略attributes设置。
    • characterDataOldValue :如果characterData为true或省略,则相当于设置为true,表示需要记录改变之前的目标数据,设置了characterDataOldValue可以省略characterData设置。
    • attributeFilter:如果不是所有的属性改变都需要被观察,并且attributes设置为true或者被忽略,那么设置一个需要观察的属性本地名称(不需要命名空间)的列表。

    现有以下以下dom:

    <div class="outer">
        <div class="inner">inner</div>
    </div>
    

    对class为outer的dom元素启动监听:

    var mutationobserve = new  MutationObserver(function(mutations) {
          //mutations是变动数组
          mutations.forEach((item) => {
                console.log(item);
          })
    })
    var outer = document.querySelector('.outer');
    mutationobserve.observe(outer,  {
          childList: true,
          attributes: true,
          characterData: true,
          subtree: true,
          attributeOldValue: true,
          characterDataOldValue: true
    })
    

    然后移除outer的子元素inner:

      outer.removeChild(outer.firstChild);
    

    输出结果如下:

    image.png

    takeRecords

    takeRecords用来取出记录队列中的记录,同时清除记录队列中的内容。

     outer.appendChild(document.createTextNode('新增Text节点'));
      //清空记录队列,此时没有输出
     var record = mutationobserve.takeRecords();    
     outer.appendChild(document.createTextNode("子节点2"))
    

    结果只有第二个变动才触发了输出:

    image.png

    以下是没有takeRecords的情况:

    image.png

    disconnect

    最后,需要通过disconnect停止对dom的监听:

    mutationobserve.disconnect();
    

    异步

    MutationObserver的回调函数是异步的,只有在全部DOM操作完成之后才会调用。

      var i = 0;
      var mutationobserve=new MutationObserver(function (mutations) {
          i++;
      });
      mutationobserve.observe(outer,{ childList: true});
      outer.appendChild(document.createTextNode('text1'));
      outer.appendChild(document.createTextNode('text2'));
      console.log(i) 
    

    结果会输出0

    image.png

    再输出一次i,i等于1

    image.png

    验证了MutationObserver会等待当前所有dom操作完成后再触发。

    相关文章

      网友评论

        本文标题:你所不知道的MutationObserver

        本文链接:https://www.haomeiwen.com/subject/abuysctx.html