介绍

它和 IntersectionObserver, ResizeObserver 差不多, 都是观察 element 变化的.

它可以观察元素的 attribute 增加, 移除, 修改, append child 等等.

建议先看前 2 篇 IntersectionObserverResizeObserver 一起了解会比较容易.

new MutationObserver()

const mo = new MutationObserver((mutations) => {
console.log("mutations", mutations);
}); mo.observe(document.querySelector(".container"), {
attributes: true,
});

调用方式和 Intersection, ResizeObserver 是一样的.

注意: 它和 IO 和 Resize 有个区别,  IO, Resize 调用 observe 第一次会马上触发掉, 但 Mutation 没有, 它会等到真的有改变时才触发.

还有一个特别之处是 observe 的时候需要一个 config. 指定要观察的范围.

出于性能考虑, 观察的范围越广性能越伤, 所以请按需设置哦.

观察 attributes

attributes: true

可以观察到元素添加, 移除, 修改 attribute. (注: 只要有 value set 即便 value 是一样的, 它依然会触发哦, 如果不想这样, 我们可以通过 oldValue 来 filter 掉)

attributeOldValue: true

多了一个 oldValue

attributeFilter: ["contenteditable"]

指定要观察的 attribute, 没有在 list 里面的, 添加, 移除, 修改都不会触发.

观察 Child 和 Descendant Element

childList: true

当元素 appendChild / removeChild 的时候触发.

subtree: true

当元素有子孙后裔插入或移除时触发.

观察 TextNode textcontent

characterData: true & characterDataOldValue: true

const textNode = document.createTextNode("Hello World");
mo.observe(textNode, { characterData: true, characterDataOldValue: true });
setTimeout(() => {
textNode.textContent = "SuperMan";
}, 3000);

效果

注意, 一定要是 TextNode 哦.

const p = document.createElement("p");
p.textContent = "Hello World";
mo.observe(p, { characterData: true, characterDataOldValue: true });
setTimeout(() => {
p.textContent = "SuperMan";
document.body.append(p);
}, 3000);

换成 p 就不灵了.

虽然 p 是有效的, 可以 append to body 看到字, 但是 observer 没有监听到它. 所以监听的节点一定要是 TextNode.

触发时机

和 IntersectionObserver,ResizeObserver 不同。

MutationObserver 触发的很早,它类似 Microtask。

而 IntersectionObserver,ResizeObserver 则是 after ui render。

也合理啦,毕竟 MutationObserver callback 获取的资料比如 addedNodes, removedNode 这些都不需要等 ui render。

window.setTimeout(() => {
const container = document.querySelector<HTMLElement>('.container')!;
const mo = new MutationObserver(
records => console.log(records[0].addedNodes.length > 0 ? 'mutation add' : 'mutation remove'), // 2, 4
);
mo.observe(container, { childList: true, subtree: true }); requestAnimationFrame(() => console.log('rAF')); // 6 const h1 = container.querySelector('h1')!;
h1.remove();
console.log('sync'); // 1 queueMicrotask(() => {
console.log('micro1'); // 3
container.appendChild(h1); queueMicrotask(() => {
console.log('micro2'); // 5
});
});
}, 2000);

效果

相当于,h1.remove 之后它就 queueMicrotask for mutation callback。

没有 unobserve 方法,但有 takeRecords 方法

相关 Issue – Disconnect single target instead of all

不像 IntersectionObserver 和 ResizeObserver 有 unobserve 可以取消指定 element 的监听,

MutationObserver 只有 disconnect 一次性取消所有监听。

workaround 的方案是 wrap 一层,然后自己记入 element,unobserve 时,调用 disconnect 然后在 re-observe 其它的回去。参考高赞回复

另外 MutationObserver  有一个 takeRecords 方法,这个方法用在 disconnect 之前,因为 MutationObserver 触发是 microtask,

所以在同步执行过程中,如果你 disconnect,这时是有可能已经有一些 MutationRecord 即将要发布的,而这个 takeRecords 方法就可以把它们拿出来处理,然后你才 disconnect。

DOM – MutationObserver的更多相关文章

  1. HTML5新特性之Mutation Observer

    Mutation Observer(变动观察器)是监视DOM变动的接口.当DOM对象树发生任何变动时,Mutation Observer会得到通知. 要概念上,它很接近事件.可以理解为,当DOM发生变 ...

  2. livequery源码解读

    从使用说起: 若干年前,有一天发现,通过js代码创建的html元素及ajax加载的html,无法被$([selector]).click(function(){...})绑定上事件,于是发现了jQue ...

  3. js实现数据视图双向绑定原理

    这个方法了不起啊..vue.js和avalon.js 都是通过它实现双向绑定的..而且Object.observe也被草案发起人撤回了..所以defineProperty更有必要了解一下了几行代码看他 ...

  4. codepen & js demos

    codepen & js demos Mutation Observer & customize resize event listener & demo https://co ...

  5. window resize & resize observer

    window resize & resize observer https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_e ...

  6. 强大的DOM变化观察者MutationObserver

    在这之前 DOM3 提供了 Mutation events 事件 DOMAttrModified DOMAttributeNameChanged DOMCharacterDataModified DO ...

  7. 使用MutationObserver对象封装一个监听DOM生成的函数

    (function(win){ 'use strict'; var listeners = []; var doc = win.document; var MutationObserver = win ...

  8. JavaScript是如何工作的:使用MutationObserver跟踪DOM的变化

    摘要: 掌握MutationObserver. 这是专门探索 JavaScript 及其所构建的组件的系列文章的第10篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是如何工 ...

  9. js dom 观察者属性 MutationObserver

    MDN上说的很清楚 MutationObserver给开发者们提供了一种能在某个范围内的DOM树发生变化时作出适当反应的能力.该API设计用来替换掉在DOM3事件规范中引入的Mutation事件 co ...

  10. MutationObserver DOM变化的观察

    简单的给MutationObserver做个测试及总结笔记. MutationObserver,window上的一个(构造)函数,可以通过其创建的观察者(观察对象)达到观察DOM的变化的效果. 可适用 ...

随机推荐

  1. el-date-picker的value-forma在Element UI (Vue 2)和Element Plus (Vue 3)中的不同

    Element UI (Vue 2): <template> <el-form-item prop="register_date" label="成立日 ...

  2. 基于微信小程序+Springboot校园二手商城系统设计和实现

    \n文末获取源码联系 感兴趣的可以先收藏起来,大家在毕设选题,项目以及论文编写等相关问题都可以给我加好友咨询 一. 前言介绍: 在当今社会的高速发展过程中,产生的劳动力越来越大,提高人们的生活水平和质 ...

  3. [oeasy]python0024_ 输出时间_time_模块_module_函数_function

    ​ 输出时间 回忆上次内容 ​print​​函数 有个默认的 ​​end参数​ ​​end参数​​ 的值可以是任意字符串 ​​end参数​​ 的值会输出到结尾位置 ​​end参数​​ 的默认值是 ​​ ...

  4. Day 5 - 双指针与折半搜索

    双指针 本页面将简要介绍双指针. 引入 双指针是一种简单而又灵活的技巧和思想,单独使用可以轻松解决一些特定问题,和其他算法结合也能发挥多样的用处. 双指针顾名思义,就是同时使用两个指针,在序列.链表结 ...

  5. .NET 控件转图片

    Windows应用开发有很多场景需要动态获取控件显示的图像,即控件转图片,用于其它界面的显示.传输图片数据流.保存为本地图片等用途. 下面分别介绍下一些实现方式以及主要使用场景 RenderTarge ...

  6. git篇-- Git在项目实操中常见的使用命令--02

    Git是现代软件开发中不可或缺的版本控制工具.它能帮助开发者跟踪项目的所有变更,并与团队成员高效协作.本文将介绍一些在项目实操中常见的Git命令,帮助你更好地管理代码. 1. 初始化和配置 初始化仓库 ...

  7. 13、Spring之JdbcTemplate

    13.1.环境搭建 13.1.1.创建module 13.1.2.选择maven 13.1.3.设置module名称和路径 13.1.4.module初始状态 13.1.5.配置打包方式和依赖 < ...

  8. 【SpringBoot】10 Web开发 Part1 静态资源

    使用SpringBoot创建工程的方式: 1.在IDEA集成的Boot官网选项中点选可能需要的框架环境即可 2.SpringBoot已经设置好了这些场景,只需要配置文件中指定少量配置就可以运行起来 3 ...

  9. 【OracleDB】 09 创建和管理表

    Oracle常见的数据库对象 - 表 基本的数据存储集合,行与列组成 - 视图 抽取的逻辑集合 - 序列 提供规律性的数值 - 索引 提高查询效率 - 同义词 对象别名 TABLE 表 用户定义的表: ...

  10. 【Shiro】08 SpringBoot整合

    需要的依赖的坐标: <!-- Shiro依赖 --> <dependency> <groupId>com.github.theborakompanioni</ ...