在您提供的代码中,MutationObserver
监听属性变更,并且在检测到某个特定属性(如 data-example
)被修改时,您又手动将其值改回旧值。这会导致递归调用,因为当您使用 setAttribute
恢复旧值时,又会触发 MutationObserver
的回调函数,造成无限循环。
为了解决这个问题,可以采取以下几种方法:
- 禁用观察者:在恢复旧值之前,先停止观察,然后再恢复值,再重新启用观察器。
const observer = new MutationObserver((mutationsList) => {
for (let mutation of mutationsList) {
if (mutation.type === 'attributes') {
console.log(`属性 '${mutation.attributeName}' 已被修改`);
console.log('旧值:', mutation.oldValue);
if (mutation.attributeName === 'data-example') {
const newValue = targetNode.getAttribute('data-example');
// 如果新的值不符合预期,可以将其改回旧值(如用 oldValue)
if (newValue !== "expected value") {
observer.disconnect(); // 停止观察
targetNode.setAttribute('data-example', mutation.oldValue);
console.log('已恢复为旧值:', mutation.oldValue);
observer.observe(targetNode, { attributes: true, attributeOldValue: true }); // 重新开始观察
}
}
}
}
});
// 开始观察目标节点
observer.observe(targetNode, { attributes: true, attributeOldValue: true });
- 添加标志位:通过设置一个标志位来避免重复操作。
let isRestoring = false;
const observer = new MutationObserver((mutationsList) => {
for (let mutation of mutationsList) {
if (mutation.type === 'attributes' && !isRestoring) {
console.log(`属性 '${mutation.attributeName}' 已被修改`);
console.log('旧值:', mutation.oldValue);
if (mutation.attributeName === 'data-example') {
const newValue = targetNode.getAttribute('data-example');
// 如果新的值不符合预期,可以将其改回旧值(如用 oldValue)
if (newValue !== "expected value") {
isRestoring = true; // 设置标志位
targetNode.setAttribute('data-example', mutation.oldValue);
console.log('已恢复为旧值:', mutation.oldValue);
isRestoring = false; // 重置标志位
}
}
}
}
});
// 开始观察目标节点
observer.observe(targetNode, { attributes: true, attributeOldValue: true });
以上两种方法都可以有效地避免递归调用的问题。选择适合您的具体应用场景的方法即可。
内容由零声教学AI助手提供,问题来源于学员提问