attributefilter 必须与 attributes: true 配合使用才生效,且仅对 element 节点有效;监听 class/style 需确保通过 setattribute 触发,推荐使用 data-* 属性;读取新旧值应分别用 getattribute 和 attributeoldvalue: true。

attributeFilter 必须和 attributes: true 一起用
单独写 attributeFilter: ['data-status'] 不会生效,MutationObserver 默认压根不监听任何属性变化。必须显式启用 attributes: true,否则整个属性监听通道是关闭的。常见错误是只配了 attributeFilter 就以为能抓到变化,结果回调一动不动。
另外,attributes: true 只对 Element 节点有效——不能观察 Text 或 Document 节点的“属性”,因为它们没有 attribute 概念。
-
attributes: true是总开关,attributeFilter是过滤器,二者缺一不可 - 目标节点必须是
Element(比如<div>、<code><span></span>),document.body可以,document.createTextNode('x')不行 - 如果同时需要旧值比对,还得加
attributeOldValue: true,否则mutation.oldValue永远是undefined -
attributeFilter: ['class']只捕获setAttribute('class', ...)和removeAttribute('class') -
el.classList.add('x')内部虽可能调用 setAttribute,但不保证——不同浏览器/版本行为不一致,别依赖 - 推荐监听
data-类属性,比如data-loading,它天然无反射干扰,所有修改都走 attribute 接口 - 检查 HTML 源码,确认属性名拼写、连字符、全小写
- 在回调里用
mutation.attributeName打印实际触发的属性名,用于调试匹配逻辑 - 多个属性用数组明确列出:
attributeFilter: ['data-status', 'data-id', 'aria-expanded'],避免监听全部带来的冗余 - 不要写
mutation.target.className,它返回的是当前 property 值,可能已被其他代码覆盖,不是 mutation 记录的那次变更 - 对于
style,getAttribute('style')返回字符串(如"color:red"),而target.style.color是解析后的 property,二者语义不同 - 如果没开
attributeOldValue: true,mutation.oldValue是undefined,且不会报错,容易误判为“没变”
监听 class 或 style 需要绕过 DOM property 干扰
直接写 el.className = 'active' 或 el.style.color = 'red' 不会触发 attributeFilter 回调,因为这是修改 DOM property,不是 HTML attribute。只有 el.setAttribute('class', 'active') 或 el.setAttribute('style', 'color:red') 才算真正的 attribute 变更。
所以如果你用的是框架(Vue/React)或现代 API(classList.toggle),默认不会进 MutationObserver 队列。想监听 class 切换,得确保业务侧统一走 setAttribute 路径,或者改用 attributeFilter: ['class'] + 手动封装 class 操作函数。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
data-* 属性名大小写和连字符要严格匹配
attributeFilter 匹配的是原始 HTML 属性名,不是 JS 的 dataset 键名。比如 HTML 中写 <div data-user-id="123">,那么 <code>attributeFilter 必须写成 ['data-user-id'],写成 ['dataUserId'] 或 ['userId'] 都无效。
同样,data_status 是非法 HTML 属性名(下划线不被允许),即使你硬写了,MutationObserver 也不会识别。浏览器解析时会忽略或转义,导致监听失败。
回调里读取新值要用 getAttribute,别用 property
当 mutation.type === 'attributes' 时,mutation.attributeName 告诉你哪个属性变了,但新值不在 mutation.target.xxx 上——比如改了 style,mutation.target.style 是 DOM property 对象,而 mutation 只记录 attribute 字符串变更。
正确读法是 mutation.target.getAttribute(mutation.attributeName)。旧值则依赖 attributeOldValue: true 后的 mutation.oldValue。
真正难的不是写对配置,而是确认变化来源是否走的是 attribute 接口。很多看似“改了 class”的操作,底层根本没碰 attribute,这时候再怎么配 attributeFilter 都是空转。










