joken-前端工程师

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::

MutationObserver 是一个用于观察 DOM 树变化的接口,可以监测节点的添加、删除、属性变化等。以下是如何使用 MutationObserver 的基本示例:

1. 创建一个 MutationObserver 实例

// 创建一个观察者实例
const observer = new MutationObserver((mutationsList, observer) => {
    for (let mutation of mutationsList) {
        if (mutation.type === 'childList') {
            console.log('子节点发生变化');
        } else if (mutation.type === 'attributes') {
            console.log(`属性变化: ${mutation.attributeName}`);
        }
    }
});

2. 配置观察的目标和选项

要观察的目标需要通过 observe 方法设置,您可以指定要观察的类型。

const targetNode = document.getElementById('myElement');

// 配置观察选项
const config = {
    childList: true,      // 观察子节点的变化
    attributes: true,     // 观察属性变化
    subtree: true          // 观察所有后代节点
};

// 开始观察
observer.observe(targetNode, config);

3. 触发变化以测试观察者

// 添加子节点
const newChild = document.createElement('div');
newChild.textContent = '新子节点';
targetNode.appendChild(newChild);

// 修改属性
targetNode.setAttribute('data-changed', 'true');

4. 停止观察

如果需要停止观察,可以调用 disconnect 方法:

observer.disconnect();

完整示例

下面是一个完整的示例,展示如何使用 MutationObserver

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MutationObserver 示例</title>
</head>
<body>
    <div id="myElement">
        <p>初始内容</p>
    </div>
    <button id="addChild">添加子节点</button>
    <button id="changeAttr">修改属性</button>

    <script>
        const targetNode = document.getElementById('myElement');

        const observer = new MutationObserver((mutationsList) => {
            for (let mutation of mutationsList) {
                if (mutation.type === 'childList') {
                    console.log('子节点发生变化');
                } else if (mutation.type === 'attributes') {
                    console.log(`属性变化: ${mutation.attributeName}`);
                }
            }
        });

        const config = {
            childList: true,
            attributes: true,
            subtree: true
        };

        observer.observe(targetNode, config);

        document.getElementById('addChild').addEventListener('click', () => {
            const newChild = document.createElement('div');
            newChild.textContent = '新子节点';
            targetNode.appendChild(newChild);
        });

        document.getElementById('changeAttr').addEventListener('click', () => {
            targetNode.setAttribute('data-changed', 'true');
        });
    </script>
</body>
</html>

MutationObserver 不能直接监听尚未渲染的 Vue 组件的 DOM,因为它需要目标节点已经存在于 DOM 中才能进行观察。以下是一些相关的要点:

1. 组件挂载后的观察

在 Vue 组件挂载后,可以使用 mounted 钩子来创建和启动 MutationObserver。此时,组件的 DOM 已经被渲染,可以进行观察。

export default {
  mounted() {
    const targetNode = this.$el; // 或者获取特定的子节点
    const observer = new MutationObserver((mutationsList) => {
      mutationsList.forEach((mutation) => {
        console.log(mutation);
      });
    });

    const config = { childList: true, subtree: true };
    observer.observe(targetNode, config);
  }
};

2. 在数据变化时进行观察

如果希望观察的节点在初始渲染时不存在,可以在相关数据更新时动态添加观察逻辑。例如,可以在 watch 中观察数据变化,然后创建 MutationObserver

watch: {
  someData(newValue) {
    this.$nextTick(() => {
      const targetNode = this.$el;
      // 创建和启动观察者
    });
  }
}

3. 使用 $nextTick

由于 Vue 的异步渲染机制,建议使用 $nextTick 确保 DOM 已经更新并可被观察。

this.$nextTick(() => {
  // 在这里使用 MutationObserver
});

4. 总结

  • MutationObserver 只对已渲染的 DOM 生效。
  • 使用 Vue 的生命周期钩子(如 mounted)或 $nextTick 来确保在 DOM 可用时设置观察器。
  • 对于动态组件或异步加载的内容,需要确保组件渲染完成后再进行观察。

总结

  • 使用 MutationObserver 可以轻松监测 DOM 的变化。
  • 配置选项允许观察不同类型的变化,包括子节点变化和属性变化。
  • 使用 disconnect 方法可以停止观察。
posted on 2024-07-04 00:12  joken1310  阅读(0)  评论(0编辑  收藏  举报