我打算使用MutationObserver来观察元素值的外观和变化,但说实话我不确定应该如何实现它。
MO的目标是div.player-bar
,我想要完成的是检测el-badge__content
何时出现在页面中以及当el-badge__content
元素值发生变化时(例如1
将改为2
)。
请注意el-badge__content
与div.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循环或调用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);
}
如您所见,第二个观察者被添加到徽章元素本身。移除徽章元素后,垃圾收集器将自动删除观察者。