MutationObserver 检测元素外观和元素值的变化

MutationObserver detecting element appereance and changing of element's value

我打算使用 MutationObserver 来观察元素值的外观和变化,但老实说我不确定应该如何实现。

MO 的目标是 div.player-bar,我想要完成的是检测 el-badge__content 何时出现在页面中以及何时更改 el-badge__content 元素值(例如相反 1 将更改为 2).

请注意 el-badge__contentdiv.new-bar 的创建同时出现,很多时候 div.new-bar 不会出现在页面中,这就是为什么我需要听div.player-bar.

这可能吗?到目前为止,我在想这样的事情:

var target = document.getElementsByClassName('player-bar')[0];
var config = { attributes: true, childList: true, subtree: true };

const observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    mutation.forEach(function(addedNode) {
      var e = addedNode.document.getElementsByClassName('el-badge__content')[0];
      if (e) {
        console.log("Element appearance/changed")
      };
    });
  });
});

observer.observe(target, config);

提前致谢。

mutation 是一个 MutationRecord object,它包含您在代码中遗漏的类数组 addedNodes NodeList 集合,但它不是数组,因此它没有 forEach。您可以在现代浏览器中使用 ES6 for-of 枚举或普通 for 循环或调用 forEach.call.

对于这种特殊情况,一个更简单的解决方案是使用 getElementsByClassName 返回的动态更新的实时集合,因为它速度超快,通常比枚举所有变异记录及其添加的所有节点要快得多。

const target = document.querySelector('.player-bar');
// this is a live collection - when the node is added the [0] element will be defined
const badges = target.getElementsByClassName('el-badge__content');
let prevBadge, prevBadgeText;

const mo = new MutationObserver(() => {
  const badge = badges[0];
  if (badge && (
      //  the element was added/replaced entirely
      badge !== prevBadge ||
      // or just its internal text node
      badge.textContent !== prevBadgeText
  )) {
    prevBadge = badge;
    prevBadgeText = badge.textContent;
    doSomething();
  }
});
mo.observe(target, {subtree: true, childList: true});

function doSomething() {
  const badge = badges[0];
  console.log(badge, badge.textContent);
}

如您所见,第二个观察者已添加到徽章元素本身。当徽章元素被移除时,观察者将被垃圾收集器自动移除。