html 本身不能实现观察者模式,所有相关实现均依赖 javascript;mutationobserver 是监听 dom 变动的唯一标准方案;proxy 是监听 js 数据变更的最小可行路径;data-* 属性非响应式,需自定义元素配合 attributechangedcallback;eventtarget 仅作轻量事件总线,不满足 observer 模式核心特征。

HTML 本身不能实现观察者模式——它只是标记语言,没有内置的订阅/通知机制。所有“HTML 实现观察者模式”的说法,实际都依赖 JavaScript 在浏览器环境中桥接 DOM 与业务逻辑。
MutationObserver 是监听 DOM 变动的唯一标准方案
当你需要知道某个元素被插入、属性被改、文本被替换,MutationObserver 是当前唯一靠谱且性能可控的原生 API。
- 必须显式调用
observe()才会开始监听;不调就完全静默 - 回调接收的是
MutationRecord[]数组,不是单个事件对象,需遍历处理每个记录 -
childList: true只监听直接子节点;要捕获深层变动,必须加subtree: true - 目标元素被移除后若未调
disconnect(),observer 实例可能长期持有对已卸载节点的引用,造成内存泄漏
Proxy + 自定义 onChange 是监听 JS 数据变更的最小可行路径
想让一个普通对象(如 data)变时自动触发 UI 更新,Proxy 是目前最直接的方式,比 Object.defineProperty 支持更全(能拦截新增/删除属性)。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
-
set拦截赋值,deleteProperty拦截删除,ownKeys拦截Object.keys等枚举操作 - 不要在 handler 里直接操作 DOM;应调用传入的
onChange回调,把“通知”和“响应”解耦 -
Proxy无法代理原始值(string、number)、null或数组索引赋值(arr[0] = x),后者需配合Reflect.set(arr, 0, x)手动兜底
data-* 属性不是响应式通道,别把它当状态源
dataset 只适合初始化传参,浏览器不会因它变化而通知 JS。想让它“可观察”,必须走自定义元素 + attributeChangedCallback 这条路。
- 必须在
observedAttributes静态 getter 中显式声明小写连字符格式属性名(如'data-id'),不支持通配符 - 变更必须用
setAttribute('data-id', '123'),用dataset.id = '123'不会触发回调 - 所有
data-*值始终是字符串;data-count="42"读出来是'42',不是数字,解析前得校验非空和格式
EventTarget 不是 Observer 模式,但可作轻量事件总线
EventTarget 提供了 dispatchEvent / addEventListener,但它只是浏览器事件分发机制,缺少 Observer 模式的核心特征:被观察者主动维护观察者列表、状态变更时广播通知。
- 它不保存订阅关系,也不感知“谁在监听什么”,纯靠事件名字符串匹配
- 适合跨组件松耦合通信(如
new CustomEvent('form:submit', { detail })),但无法做细粒度状态同步 - 手动清理很重要:
removeEventListener必须传入与addEventListener完全相同的函数引用,否则无效
真正难的不是选哪个 API,而是明确你要观察什么:DOM 结构?JS 对象字段?还是自定义语义事件?三者技术路径完全不同,混用会导致状态不同步或监听失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










