Attribute changes with MutationObserver only found if code is inside a loop

huangapple go评论55阅读模式
英文:

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;
  }
}

huangapple
  • 本文由 发表于 2023年2月19日 20:00:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75499998.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定