【问题标题】:Why doesn't my MutationObserver object disconnect?为什么我的 MutationObserver 对象没有断开连接?
【发布时间】:2019-07-20 05:29:17
【问题描述】:

我有一个 MutationObserver 对象,该对象在函数内使用其回调函数进行初始化,并观察一个节点,该节点的其中一个子文本每两秒更改一次,以便将另一个节点的文本更改为始终与另一种带有回调函数。

在同一个函数中,我检查对象的属性是否与函数的参数相同。如果是,则初始化 MutationObserver 对象,如果不是,则在 try catch 中断开 MutationObserver 对象。

但是即使 MutationObserver 对象看似成功断开连接,它仍然会执行其回调函数并更改同一节点的文本,即使它已断开连接。

我尝试在函数外部声明观察者变量,但它仍然不起作用。 这是我的代码一般如何工作的示例:

var observer;
var objectList = [{
        id: 1,
        text: "ObjectA",
    },
    {
        id: 2,
        text: "ObjectB",
    },
    {
        id: 3,
        text: "ObjectC",
    }
]

function changeText(id) {
    var i, callback, config;
    for (i = 0; i < objectList.length; i++) {
        if (objectList[i].id === id) {
            config = {
                characterData: true
            };
            callback = function () {
                document.getElementById("textNode").innerHTML = document.getElementById("otherTextNode").innerHTML;
            };
            observer = new MutationObserver(callback);
            observer.observe(document.getElementById("otherTextNode"), config)
            return;
        }
    }
    document.getElementById("textNode").innerHTML = "";
    try {
        observer.disconnect();
    } catch (e) {
        document.getElementById("textNode").innerHTML = e.message;
    }
}

因此,当使用对象的 id 属性之一作为参数调用函数 changeText() 时,MutationObserver 被初始化并开始观察,但是当参数与 id 不匹配时,MutationObserver 应该停止,但在我的情况下它继续运行,显示的消息是“观察者未定义”,即使在它被定义为 MutationObserver 并且它继续观察之后。

【问题讨论】:

  • 因为您没有为您创建的每个观察者实例调用observer.disconnect();
  • 你可以尝试在它的回调函数中断开观察者的连接:stackoverflow.com/questions/41323897/…
  • 谢谢它的工作,但是当我尝试它时出现了一个新问题......我忘了提到虽然“otherTextNode”出现在网页上,但“textNode”只出现在引导模式上,我需要“textNode”在模态仍然存在时继续更改,但是当观察者在其回调函数内断开连接时,“textNode”仅在我需要它继续更改时更改一次。
  • 好的,我的问题在下面的答案中得到了解决。

标签: javascript


【解决方案1】:

您必须将 try/catch 移动到函数的顶部,这样当观察者已经存在时,您可以在覆盖之前将其删除。

考虑以下场景:

我点击一个有效的 id,一个 MutationObserver 被附加。

我单击第二个有效 id,附加了一个新的 MutationObserver,并且 try/catch 永远不会运行以断开前一个观察者的连接,因为循环内的 return 语句将终止函数到达 try/catch 块。

所以现在observer 指的是您创建的第二个回调,您无法再删除第一个回调。

所以我会写这样的东西:

function changeText(id) {
    if ( observer ) observer.disconnect();
    const match = objectList.find( entry => entry.id === id );
    if ( match ) {
        config = {
            characterData: true
        };
        callback = function () {
            document.getElementById("textNode").innerHTML = document.getElementById("otherTextNode").innerHTML;
        };
        observer = new MutationObserver(callback);
        observer.observe(document.getElementById("otherTextNode"), config);
    }
};

这是一个很好的例子,为什么使用在函数内部修改的全局变量而不是使用显式参数会导致问题,因为值可以在几个不同的地方发生变化。

【讨论】:

  • 感谢它的工作!本来observer是函数内部的一个变量,后来我把它移成了一个全局变量,因为我想是因为在第一次调用函数时第一次初始化的时候没有断开它,在下面的之后就不能断开了来电。
猜你喜欢
  • 2016-05-19
  • 2021-01-19
  • 2018-02-10
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-06
  • 1970-01-01
相关资源
最近更新 更多