JavaScript: прослушивание изменений DOM по указанному тегу c без опроса - PullRequest
1 голос
/ 26 апреля 2020

Я хочу создать прослушиватель, который обнаружит изменения в указанном теге, когда обновления DOM будут применены к новому тегу. В этом случае у меня есть приложение чата, и мне нужно получить все новые теги <audio> и применить класс только к этим новым тегам.

Как создать указанный прослушиватель только для одного тега?

По соображениям производительности я не хочу создавать setInterval. Есть ли другой способ добиться этого и как?

1 Ответ

2 голосов
/ 26 апреля 2020

Если я правильно понимаю, вы хотели бы определить, когда элемент <audio/> добавлен в ваш документ, и, обнаружив это событие, назначить класс CSS этому вновь добавленному элементу audio.

Одной из возможностей избежать опроса было бы использование MutationObserver - простое решение состояло бы в том, чтобы наблюдать элемент body для любых изменений его childList или subtree и для любого Обнаруженные изменения, вызванные вновь добавленным узлом audio, добавьте к этому узлу audio требуемый класс:

/* Mutation handler will assign "addedAudio" class to
any newly added audio elements */
function onMutation(mutations) {

  for (const mutation of mutations) {
    if (mutation.type === 'childList') {

      /* This mutation type is a change to tree nodes in dom */
      for (const addedNode of mutation.addedNodes) {
        if (addedNode.nodeName === 'AUDIO') {

          /* The node triggering this mutation is an audio node */
          addedNode.classList.add("addedAudio");
        }
      }
    }
  }
}

/* Create dom mutation observer with callback, and
bind observer to body (eg "root") of your web app
and watch all children and subtrees for any changes */
(new MutationObserver(onMutation))
.observe(document.querySelector("body"), {
  childList: true,
  subtree: true
})

/* For demo purpose only to simulate adding new audio element to document */
document.querySelector('button').addEventListener('click', () => {

  const audio = document.createElement("audio");
  audio.setAttribute('controls', true);
  audio.setAttribute('src', 'https://www.w3schools.com/html/horse.ogg');

  document.body.prepend(audio);
});
.addedAudio {
  border: 1px solid red;
}
<button>Add audio</button>

Обратите внимание, что более эффективным подходом было бы наблюдать узел DOM, у которого меньше дочерних элементов, мелкое поддерево и т. Д. c. Например, если все элементы audio добавлены к общему элементу DOM, рассмотрите возможность наблюдения этого элемента вместо body.

Надеюсь, что это какой-то пользователь!

...