代码之家  ›  专栏  ›  技术社区  ›  microo8

如何测试MutationObserver

  •  1
  • microo8  · 技术社区  · 8 年前

    我想同步一些DOM节点属性。如果某个属性发生更改,则会更改其他元素属性。

    在里面 this example #div1 给另外两个人。

    html:

    <div id="div1" class="foo"></div>
    <div id="div2" class="foo"></div>
    <div id="div3" class="foo"></div>
    

    js:

    let div1 = document.getElementById("div1")
    let div2 = document.getElementById("div2")
    let div3 = document.getElementById("div3")
    
    var observer = new MutationObserver(function(mutations) {
      mutations.forEach(function(mutation) {
        console.log(mutation.target.getAttribute("class"))
        //sync the new attribute value to
        div2.setAttribute("class", mutation.target.getAttribute("class"))
        div3.setAttribute("class", mutation.target.getAttribute("class"))
      })
    })
    // pass in the target node, as well as the observer options
    observer.observe(div1, { attributes: true, attributeFilter: ["class"]})
    
    //the test sets the class attribute of div1 to 'bar'
    div1.setAttribute("class", "bar")
    //then checks if div2 and div3 class is set to 'bar'
    console.log("is div2.class = 'bar'?", div2.getAttribute("class") == "bar")
    console.log("is div3.class = 'bar'?", div3.getAttribute("class") == "bar")
    

    is div2.class = 'bar'? false
    is div3.class = 'bar'? false
    bar
    

    MutationObserver 仅在检查后运行,然后 div2.class div3.class 设置为 'bar'

    1 回复  |  直到 8 年前
        1
  •  2
  •   Alex K    8 年前

    在检查更新的类之前,需要等待变异观察器处理变异事件。

    setTimeout 看见 this question 了解其工作原理。

    let div1 = document.getElementById("div1");
    let div2 = document.getElementById("div2");
    let div3 = document.getElementById("div3");
    
    var observer = new MutationObserver(function(mutations) {
      mutations.forEach(function(mutation) {
        console.log(mutation.target.getAttribute("class"));
        div2.setAttribute("class", mutation.target.getAttribute("class"));
        div3.setAttribute("class", mutation.target.getAttribute("class"));
      });
    });
    // pass in the target node, as well as the observer options
    observer.observe(div1, {
      attributes: true,
      attributeFilter: ["class"]
    });
    
    function testMutationObserver(mutation, afterMutation) {
      //Perform the mutation, e.g. by setting a new class
      mutation();
      
      //setTimeout gives the MutationObserver a chance to see the changes
      setTimeout(afterMutation);
    }
    
    testMutationObserver(
      function() {
        div1.setAttribute("class", "bar");
      },
      function() {
        console.log("is div2.class = 'bar'?", div2.getAttribute("class") == "bar");
        console.log("is div3.class = 'bar'?", div3.getAttribute("class") == "bar");
      }
    );
    <div id="div1" class="foo"></div>
    <div id="div2" class="foo"></div>
    <div id="div3" class="foo"></div>