重新连接和断开MutationObserver [英] Reconnect and disconnect a MutationObserver

查看:62
本文介绍了重新连接和断开MutationObserver的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是这个的续集.但是,没有必要阅读前一篇,我只是为感兴趣的读者提供一个链接.

This question is the sequel of this one. However, it is not necessary to read the previous, I'm just giving a link for interested readers.

有一个观察者,它将对某个类的每个元素做出反应,如@Shomz建议的那样:

There is an observer, which will react on every element with some class, as @Shomz suggested:

var target = document.querySelectorAll(".someclass");
for (var i = 0; i < target.length; i++) {
    create(target[i]);
}

function create(t) {
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            var foo = t.getAttribute("aaa")
            if (foo == "vvv")
                t.style.backgroundColor = "red";
        });
    });

    var config = {
        attributes: true
    };

    observer.observe(t, config);
}

因此,有两个密切相关的问题.

So, there are two closely intertwined questions.

1)出于某些原因,观察者可能会断开连接.如何重新连接?我尝试使用 observer.observe ,但是在这里不起作用.

1) For some reasons, the observer may be disconnected. How I can reconnect it? I tried to use observer.observe, but it doesn't work here.

2)第二个问题是,手动断开观察者连接的方法是什么?我尝试使用 observer.disconnect(); ,但是它也不起作用.

2) And the second question, what is the way to manually disconnect an observer? I tried to use observer.disconnect();, but it is also doesn't work.

推荐答案

1)出于某些原因,观察者可能会断开连接.如何重新连接?我试图使用observer.observe,但在这里不起作用.

1) For some reasons, the observer may be disconnected. How I can reconnect it? I tried to use observer.observe, but it doesn't work here.

2)第二个问题是,手动断开观察者连接的方法是什么?我尝试使用observer.disconnect();,但是它也不起作用.

2) And the second question, what is the way to manually disconnect an observer? I tried to use observer.disconnect();, but it is also doesn't work.

您处在正确的轨道上,但事实是您正在尝试在其定义的功能之外使用 observer 变量,这意味着其范围之外,因此该变量不存在(返回未定义).

You are on the right track, but the thing is you're trying to use the observer variable outside of the function it's defined in, meaning outside of its scope, so it doesn't exist (returns undefined).

请参阅我的原始代码更新示例.我已经将观察者移动到一个数组中,并使其可以在该函数之外访问,因此您可以正常断开连接并重新连接它们.

See my updated example of your original code. I've moved the observers into an array and made it accessible outside of that function, so you can disconnect and reconnect them normally.

问题只是保留对观察者的引用,就像您保留对目标元素的引用一样.

The issue was just keeping references to observers, just like you were keeping references to the target elements.

var msg = document.getElementById('msg');
var target = document.querySelectorAll(".someClass");
// an array of observers
var observers = [];
// configuration of the observer
var config = { attributes: true };

for (var i = 0; i < target.length; i++) {

    // create an observer instance
    observers[i] = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            var foo = mutation.target.getAttribute("bgColor")

            if (foo)
                mutation.target.style.backgroundColor = foo;
        });
    });

    // pass in the target node, as well as the observer options
    observers[i].observe(target[i], config);
}

msg.textContent = 'Starting timeouts';
// let's change an attribute in a second
setTimeout(function(){
  target[2].setAttribute('bgColor', 'red');
  msg.textContent = 'Mutation observer should change the box to red';
}, 2000);

setTimeout(function(){
  target[2].setAttribute('bgColor', 'green');
  msg.textContent = 'Mutation observer should change the box to green';
}, 4000);

setTimeout(function(){
  observers[2].disconnect();
  msg.textContent = 'Mutation observer disconnected';
}, 6000);

setTimeout(function(){
  target[2].setAttribute('bgColor', 'blue');
  msg.textContent = 'Mutation observer tries to change the box to blue, but is disconnected';
}, 8000);

setTimeout(function(){
  target[1].setAttribute('bgColor', 'blue');
  msg.textContent = 'Let\'s try another box, which is not disconnected, all good';
}, 10000);

setTimeout(function(){
  observers[2].observe(target[2], config);
  msg.textContent = 'Mutation observer reconnected';
}, 12000);

setTimeout(function(){
  target[2].setAttribute('bgColor', 'red');
  msg.textContent = 'Finally, the reconnected mutation observer should change the box to red';
}, 14000);

setTimeout(function(){
  target[1].setAttribute('bgColor', 'white');
  target[2].setAttribute('bgColor', 'white');
  msg.textContent = 'Now try the manual controls below';
  document.getElementById('ctrl').style.display = 'block';
}, 16000);

.someClass {
  width: 50px;
  height: 50px;
  display: inline-block;
  border: 1px solid black
}

#ctrl {display: none}

<div class="someClass"></div>
<div class="someClass"></div>
<div class="someClass"></div>
<div class="someClass"></div>
<p id="msg"></p>
<hr>
<div id="ctrl">
<p>Change attribute: 
<button onclick="target[2].setAttribute('bgColor', 'red');">Red</button>
<button onclick="target[2].setAttribute('bgColor', 'green');">Green</button>
<button onclick="target[2].setAttribute('bgColor', 'blue');">Blue</button>
</p><p>Manage the observer
<button onclick="observers[2].disconnect();">Disconnect</button>
<button onclick="observers[2].observe(target[2], config);">Reconnect</button>
</p>
</div>

更新

根据要求,以上方法将我的第一个示例放入另一个(链接的)问题中.基本上,只是用于创建观察者的外部函数.

As requested, the above approach put inside my first example in the other (linked) question. Basically, just an externalized function for creating observers.

var msg = document.getElementById('msg');
var target = document.querySelectorAll(".c");
// an array of observers
var observers = [];
// configuration of the observer
var config = { attributes: true };

for (var i = 0; i < target.length; i++) {
  create(target[i], i);
}

function create(t, i) {
  // create an observer instance
  observers[i] = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      var foo = t.getAttribute("bgColor")

      if (foo)
        t.style.backgroundColor = foo;
    });
  });

  // pass in the target node, as well as the observer options
  observers[i].observe(t, config);
}

// let's change an attribute in a second
msg.textContent = 'Starting timeouts';
// let's change an attribute in a second
setTimeout(function(){
  target[2].setAttribute('bgColor', 'red');
  msg.textContent = 'Mutation observer should change the box to red';
}, 2000);

setTimeout(function(){
  target[2].setAttribute('bgColor', 'green');
  msg.textContent = 'Mutation observer should change the box to green';
}, 4000);

setTimeout(function(){
  observers[2].disconnect();
  msg.textContent = 'Mutation observer disconnected';
}, 6000);

setTimeout(function(){
  target[2].setAttribute('bgColor', 'blue');
  msg.textContent = 'Mutation observer tries to change the box to blue, but is disconnected';
}, 8000);

setTimeout(function(){
  target[1].setAttribute('bgColor', 'blue');
  msg.textContent = 'Let\'s try another box, which is not disconnected, all good';
}, 10000);

setTimeout(function(){
  observers[2].observe(target[2], config);
  msg.textContent = 'Mutation observer reconnected';
}, 12000);

setTimeout(function(){
  target[2].setAttribute('bgColor', 'red');
  msg.textContent = 'Finally, the reconnected mutation observer should change the box to red';
}, 14000);

setTimeout(function(){
  target[1].setAttribute('bgColor', 'white');
  target[2].setAttribute('bgColor', 'white');
  msg.textContent = 'Now try the manual controls below';
  document.getElementById('ctrl').style.display = 'block';
}, 16000);

.c {
  width: 50px;
  height: 50px;
  display: inline-block;
  border: 1px solid black
}
#ctrl {display: none}

<div class="c"></div>
<div class="c"></div>
<div class="c"></div>
<div class="c"></div>
<p id="msg"></p>
<hr>
<div id="ctrl">
<p>Change attribute: 
<button onclick="target[2].setAttribute('bgColor', 'red');">Red</button>
<button onclick="target[2].setAttribute('bgColor', 'green');">Green</button>
<button onclick="target[2].setAttribute('bgColor', 'blue');">Blue</button>
</p><p>Manage the observer
<button onclick="observers[2].disconnect();">Disconnect</button>
<button onclick="observers[2].observe(target[2], config);">Reconnect</button>
</p>
</div>

这篇关于重新连接和断开MutationObserver的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆