如何测试 MutationObserver
How to test MutationObserver
我想同步一些 DOM 节点属性。如果更改了一个属性,则它会更改其他元素的属性。
我可以更改它,但我不能为它编写测试。该测试更改观察到的元素的属性,然后检查更改是否应用于其他元素。更改同步最终会发生,但不会在观察到的元素属性更改后立即发生。
在 this example 中,我创建了三个 div,并希望将 #div1
的 class 属性同步到其他两个。
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'
。所以我的问题是,如何测试属性与 MutationObserver
.
的同步
您需要等待变异观察者处理变异事件,然后才能检查更新的类。
常用技巧是使用 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>
我想同步一些 DOM 节点属性。如果更改了一个属性,则它会更改其他元素的属性。
我可以更改它,但我不能为它编写测试。该测试更改观察到的元素的属性,然后检查更改是否应用于其他元素。更改同步最终会发生,但不会在观察到的元素属性更改后立即发生。
在 this example 中,我创建了三个 div,并希望将 #div1
的 class 属性同步到其他两个。
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'
。所以我的问题是,如何测试属性与 MutationObserver
.
您需要等待变异观察者处理变异事件,然后才能检查更新的类。
常用技巧是使用 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>