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__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-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);
}
如您所见,第二个观察者已添加到徽章元素本身。当徽章元素被移除时,观察者将被垃圾收集器自动移除。
我打算使用 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-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);
}
如您所见,第二个观察者已添加到徽章元素本身。当徽章元素被移除时,观察者将被垃圾收集器自动移除。