我有一个观察者,它监听 div的属性的任何变化,如果更改了属性,它会将该div的背景颜色设置为红色。
实际上你可以自己轻松测试一下。打开Chrome的书签管理器,在控制台中启动此脚本,然后单击任何书签或文件夹。它将涂成红色。
问题在代码块的中间提到:如果我使用listitem
,脚本将被挂起。
第一种方法(使用setAttribute
)不适合我,因为在我的实际代码中,我使用的是自定义属性,而不是style.attributeName
。
问题看起来很奇怪。它可以解决的方式是什么?
background-color
答案 0 :(得分:2)
您通过更改属性来响应每个属性更改。毫无疑问,这会导致一个问题:你会让观察者再次开火。显然,setAttribute
会更新属性对象,即使您设置了相同的值(我认为这不合理,虽然它有点令人惊讶)。
相反,我只会在实际需要更改时设置它:
if (mutation.target.getAttribute("yourattr") != targetvalue) {
mutation.target.setAttribute("yourattr", targetvalue);
}
我已经检查过将属性设置为相同的值 再次触发观察者(无论如何都在Chrome上):
var target = document.getElementById("target");
var counter = 0;
var observer = new MutationObserver(function() {
++counter;
snippet.log(Date.now() + ": " + counter);
if (counter < 10) {
snippet.log("Inside handler: Setting data-foo to bar");
target.setAttribute("data-foo", "bar");
} else {
snippet.log("Inside handler: Stopped, to avoid looping forever");
}
});
observer.observe(target, {attributes: true});
snippet.log("Initial change: Setting data-something-else to testing");
target.setAttribute("data-something-else", "testing");
&#13;
<div id="target"></div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
首先检查可以防止发生这种情况:
var target = document.getElementById("target");
var observer = new MutationObserver(function() {
snippet.log(Date.now() + ": In handler");
if (target.getAttribute("data-foo") != "bar") {
snippet.log("Inside handler: Setting data-foo to bar");
target.setAttribute("data-foo", "bar");
} else {
snippet.log("Inside handler: No need to set it, it's already set");
}
});
observer.observe(target, {attributes: true});
snippet.log("Initial change: Setting data-something-else to testing");
target.setAttribute("data-something-else", "testing");
&#13;
<div id="target"></div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;