英文:
Attribute changes with MutationObserver only found if code is inside a loop
问题
我遇到了一些问题,无法检测HTML元素的属性更改,使用JavaScript和MutationObserver
。以下是代码部分:
document.addEventListener("DOMContentLoaded", function() {
const checkForLoading = setInterval(function () {
let loading = document.getElementById("sequence");
if (loading) {
console.log("loading detected");
const loadingObserver = new MutationObserver(function (mutations) {
console.log("mutation detected");
if (loading.getAttribute('data-dash-is-loading') === 'true') {
console.log("loading");
// loading.style.visibility = 'hidden';
} else {
console.log("not loading");
// loading.style.visibility = 'visible';
}
});
const observerOptions = {
attributes: true,
}
loadingObserver.observe(loading, observerOptions);
clearInterval(checkForLoading);
}
}, 100);
});
因为元素不会立刻可用,所以我设置了checkForLoading
循环。属性'data-dash-is-loading'
只在元素加载时设置,否则不可用。此代码仅在循环在检测到序列元素后继续运行且未调用clearInterval(checkForLoading)
时才有效。但我想避免不断运行这个循环。非常感谢您提供帮助以解决这个问题。
英文:
I am having some trouble detecting attribute changes of an html element with js and MutationObserver
. This is the code:
document.addEventListener("DOMContentLoaded", function() {
const checkForLoading = setInterval(function () {
let loading = document.getElementById("sequence");
if (loading) {
console.log("loading detected");
const loadingObserver = new MutationObserver(function (mutations) {
console.log("mutation detected");
if (loading.getAttribute('data-dash-is-loading') === 'true') {
console.log("loading");
// loading.style.visibility = 'hidden';
} else {
console.log("not loading");
// loading.style.visibility = 'visible';
}
});
const observerOptions = {
attributes: true,
}
loadingObserver.observe(loading, observerOptions);
clearInterval(checkForLoading);
}
}, 100);
});
Because the element is not available immediately I have the checkForLoading
loop set up. The attribute 'data-dash-is-loading'
is only set when an element is loading and otherwise not available. This code only works if the loop keeps on running after the sequence element is detected and clearInterval(checkForLoading)
is not called. However I would like to avoid running this loop constantly. Any help to fix this issue is greatly appreciated.
答案1
得分: 1
这通常意味着元素被重新创建,因此您需要观察其在DOM树中更高的祖先并添加 subtree: true
。
例如,一个父元素:
loadingObserver.observe(loading.parentElement, {attributes: true, subtree: true});
如果这一开始并没有帮助,您可以首先尝试使用 document.body
来确保变动确实发生,然后尝试各种中间祖先元素,找到保持不变的那个。
在回调函数中,您需要验证变动是否发生在您期望的元素上:
for (const m of mutations) {
if (m.target.id === 'foo') {
// 这是期望的元素,在这里对其进行操作并停止循环
break;
}
}
英文:
It usually means the element is recreated, so you need to observe its ancestor higher up the DOM tree and add subtree: true
.
For example, a parent element:
loadingObserver.observe(loading.parentElement, {attributes: true, subtree: true});
If this doesn't help at once you can try document.body
first to make sure the mutation actually happens, then try various ancestor elements in-between to find the one that stays the same.
In the callback you'll need to verify that the mutation occurred on your desired element:
for (const m of mutations) {
if (m.target.id === 'foo') {
// it's the desired element, do something about it here and stop the loop
break;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论