Как заставить один MutationObserver прослушивать изменения на нескольких элементах? - PullRequest
1 голос
/ 16 октября 2019

Я реализовал следующий код для наблюдения за изменениями в классе:

$(document).ready(function () {
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    if (mutation.attributeName === "class") {
      var attributeValue = $(mutation.target).prop(mutation.attributeName);
      console.log("Class attribute changed to:", attributeValue);
    }
  });
});

observer.observe(document.querySelector(".xxx"), {
  attributes: true
});  });

Ссылка JSFiddle: https://jsfiddle.net/8Lfj0ev3/

В идеале, я хочу, чтобы это прослушивало изменения во всех элементах класса«ххх». Но это только прослушивание первого элемента с классом xxx и игнорирование других. Как я могу это исправить?

1 Ответ

0 голосов
/ 16 октября 2019

Два способа решения этой проблемы:

Несколько observe вызовов

Вы можете позвонить observe несколько раз, чтобы просмотреть несколько элементов:

$(".xxx").each(function() {
  observer.observe(this, {
    attributes: true
  });
});

Пример Live:

$(document).ready(function() {
  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if (mutation.attributeName === "class") {
        var attributeValue = $(mutation.target).prop(mutation.attributeName);
        console.log("Class attribute changed to:", attributeValue);
      }
    });
  });
  
  $(".xxx").each(function() {
    observer.observe(this, {
      attributes: true
    });
  });
});

setTimeout(function() {
  $(".d1").addClass("x1");
}, 800);
setTimeout(function() {
  $(".d2").addClass("x2");
}, 1600);
setTimeout(function() {
  $(".d3").addClass("x3");
}, 2400);
<div class="d1 xxx"></div>

<div class="d2 xxx"> </div>

<div class="d3 xxx"> </div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Смотреть поддерево контейнера

Но другой вариант - посмотреть поддерево ближайшего контейнера, в котором они все находятся, а затем только обратить внимание наизменения, если они произошли в элементе .xxx:

var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    if (mutation.attributeName === "class") {
      var $target = $(mutation.target);                            // ***
      if ($target.hasClass("xxx")) {                               // ***
        var attributeValue = $target.prop(mutation.attributeName);
        console.log("Class attribute changed to:", attributeValue);
      }
    }
  });
});

observer.observe(document.body, {                                  // ***
  attributes: true,
  subtree: true                                                    // ***
});

Live Пример:

$(document).ready(function() {
  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if (mutation.attributeName === "class") {
        var $target = $(mutation.target);
        if ($target.hasClass("xxx")) {
          var attributeValue = $target.prop(mutation.attributeName);
          console.log("Class attribute changed to:", attributeValue);
        }
      }
    });
  });
  
  observer.observe(document.body, {
    attributes: true,
    subtree: true
  });
});

setTimeout(function() {
  $(".d1").addClass("x1");
}, 800);
setTimeout(function() {
  $(".d2").addClass("x2");
}, 1600);
setTimeout(function() {
  $(".d3").addClass("x3");
}, 2400);
<div class="d1 xxx"></div>

<div class="d2 xxx"> </div>

<div class="d3 xxx"> </div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

В этом примере ближайший контейнер - document.body, но, конечно, в вашей реальной ситуации может быть что-то ближе к элементам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...