2017-07-19 5 views
0

Ich möchte einige DOM-Knotenattribute synchronisieren. Wenn ein Attribut geändert wird, ändert es das Attribut für andere Elemente.So testen MutationObserver

Ich kann es ändern, aber ich kann einen Test dafür nicht schreiben. Der Test ändert das Attribut des beobachteten Elements und prüft dann, ob die Änderungen auf andere Elemente angewendet wurden. Die Änderungssynchronisierung wird schließlich stattfinden, jedoch nicht unmittelbar nach der Änderung des Attributs des beobachteten Elements.

In habe ich drei divs erstellt und möchte das Klassenattribut von #div1 mit anderen zwei synchronisieren.

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") 

der Ausgang ist:

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

MutationObserver läuft erst nach den Prüfungen und dann die div2.class und div3.class sind 'bar' gesetzt. Meine Frage ist also, wie man die Synchronisation von Attributen mit MutationObserver testet.

Antwort

2

Sie müssen warten, bis der Mutationsbeobachter das Mutationsereignis bearbeitet hat, bevor Sie nach den aktualisierten Klassen suchen.

Der übliche Trick besteht darin, einen setTimeout zu verwenden. Siehe this question für wie es funktioniert.

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>