2017-07-19 139 views
0

我想同步一些DOM節點屬性。如果一個屬性被改變,那麼它會改變其他的元素屬性。如何測試MutationObserver

我可以改變它,但我不能爲它寫一個測試。測試更改觀察元素的屬性,然後檢查應用於其他元素的更改。更改同步最終會發生,但不會在觀察到的元素屬性更改後立即生效。

this example我已經創建了三個div,並且想要將的class屬性同步到其他兩個div。

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.classdiv3.class被設置爲'bar'。所以我的問題是,如何測試與MutationObserver屬性的同步。

回答

2

在檢查更新的類之前,您需要等待突變觀察者處理突變事件。

常用技巧是使用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>