js mutationobserver扼要引见

视察者形式引见

视察者设想形式定义了对象间的一种一对多的依靠关联,以便一个对象的状况发作变化时,
一切依靠于它的对象都获得关照并自动革新。

一些好的文章
视察者形式与托付形式的区分
深切明白JavaScript系列(32):设想形式之视察者形式
【Javascript设想形式3】-视察者形式

MutationObserver引见

能够运用的设置

  • childList: *true =========================能够视察子元素
  • attributes: *true ========================能够视察属性
  • characterData: *true ====================能够视察数据
  • subtree: *true =========================能够视察一切子女
  • attributeOldValue: *true ==================能够保留属性旧值
  • characterDataOldValue: ==================*true 能够保留数据旧值
  • attributeFilter: ==========================设置指定视察属性元素鸠合

note: Mutation Observers 被限定能够视察Dom序列化状况 在视察textarea内内容转变时 没法触发

observe 一个被视察者对象 一份设置

void observe(
  Node target,
  MutationObserverInit options
);

disconnet 断开视察者与目的链接

void disconnect();

takeRecords 返回对象一切视察纪录

Array takeRecords();

MutationObserver运用

差别浏览器之间存在兼容性问题

  var MutationObserver = window.MutationObserver 
|| window.WebKitMutationObserver 
|| window.MozMutationObserver;

html

  <ol contenteditable oninput="">
    <li>Press enter and look at the console</li>
  </ol>

猎取list dom

var list = document.querySelector('ol');

实例化MutationObserver

var Observer = new MutationObserver(function(mutations){
});

Mutation Observer 对象

《js mutationobserver扼要引见》

监测childList

Observer.observe(list, {
  childList: true
});

不过值得注意的是 这里观察的是list直接child 假如要观察child的child 就须要开启subtree
比如要检测如许的行动

list.childNodes[0].appendChild(document.createElement('div'));

observer须要变动设置

Observer.observe(list, {
  childList: true,
  subtree: true
});

(mutationObserver观察childlist) jsbin地点

observe 罕见设置 及其诠释

observer.observe(target, {childList:true,subtree:true})                 
//subtree属性让视察行动举行"递归",这时候,以target节点为根节点的整棵DOM树发作的变化都可能会被视察到 
observer.observe(document, {childList:true,subtree:true})               
//假如target为document或许document.documentElement,则当前文档中一切的节点增添与删除操纵都邑被视察到
observer.observe(document, {childList:true,attributes:true,characterData:true,subtree:true})   
//当前文档中险些一切范例的节点变化都邑被视察到(包括属性节点的变化和文本节点的变化等)

observe 视察characterData

Observer.observe(list, {childList:true});  
//假定此时target的outHTML内容为<div>foo<div>,则: 
list.childNodes[0].data = "bar";           
//不会触发还调函数,由于childList只视察节点的新建与删除,
而这里target节点的子节点依然只要一个,没有多,没有少
Observer.observe(list, {
childList:true,characterData:true});        
//加上characterData属性,许可视察文本节点的变化,行不行? 
list.childNodes[0].data = "sds";            
//照样不会触发还调函数,由于发作变化的是target节点的子节点,我们现在的目的节点只要一个,就是target.
Observer.observe(list, {
childList:true,characterData:true,subtree:true});  
//加上subtree属性,视察一切子女节点 
list.childNodes[0].data = "cha";    

(mutationObserver观察characterdata) jsbin地点

observe 视察attribute

Observer.observe(list, {attributes:true});                    
//只视察目的节点的属性节点
list.setAttribute("foo","bar");        
//不论foo属性存在不存在,都邑触发还调函数
list.setAttribute("foo","bar");        
//纵然前后两次的属性值一样,照样会触发还调函数
list.removeAttribute("foo");            
//移除foo属性节点,触发还调函数
list.removeAttribute("foo");            
//不会触发还调函数,由于已没有属性节点可移除了
Observer.observe(list, {attributes:true,attributeFilter:["bar"]});     
//指定要视察的属性名
list.setAttribute("foo","bar");        
//不会触发还调函数,由于attributeFilter数组不包括"foo"
list.setAttribute("bar","foo"); 

(mutationObserver观察attribute) jsbin地点

我们最先做一个编辑器

功用 向前 向后而且按钮要能随时转变

ol设置为contenteditable时,当每次敲击回车时,ol的children会增添一个li 而且我们组织一个observer监听它子元素的变化, 如许我们便能够获得每次转变后一切新的children

  var observer = new MutationObserver(function(mutations) {  
    mutations.forEach(function(mutation) {
      if (mutation.type === 'childList') {
        var list_values = [].slice.call(list.children) 
            .map( function(node) { return node.innerHTML; }) 
            .filter( function(s) {
              if (s === '<br>') {
                return false;
              }
              else {
                return true;
              }
         });
        console.log(list_values);
      }
    });
  });

  observer.observe(list, {
    attributes: true, 
    childList: true, 
    characterData: true
  });

(视察ol子元素的变化) jsbin地点

编辑器对与每行变化也须要监测, 我们能够本身组织一个entry保留每次数据

var observer = new MutationObserver(function (mutations) {
    // Whether you iterate over mutations..
    mutations.forEach(function (mutation) {
      // or use all mutation records is entirely up to you
      var entry = {
        mutation: mutation,
        el: mutation.target,
        value: mutation.target.textContent,
        oldValue: mutation.oldValue
      };
      console.log('Recording mutation:', entry);
    });
  });

(ol监测每一行变化) jsbin地点

编辑器统计字数

var observer = new  MutationObserver(function(mutations){ mutations.forEach(function(mutation){
    if(mutation.type == "characterData") {
    var newValue = mutation.target.textContent;
      textinputcount.innerHTML = "还能够输入"+(1000 - newValue.length+"字");
    }
  });

编辑器统计字数

    原文作者:andypinet
    原文地址: https://segmentfault.com/a/1190000002995177
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞