customevent 的 detail 必须是 plain object,禁止传字符串、null、dom 节点、函数、map、set 或 class 实例;监听端需先判空再解构;dispatch 前须确认目标元素存在且可访问,shadow dom 中需明确指向 shadowroot;事件注册时机与作用域必须匹配冒泡路径;data-* 属性命名须全小写连字符,js 中须用 setattribute 写入,dataset 值恒为字符串。

CustomEvent 的 detail 必须是 plain object
传字符串、null 或 DOM 节点到 detail,监听方解构时大概率报错:TypeError: Cannot destructure property 'type' of e.detail as it is string。浏览器不校验,但你的代码会崩在第一行。
- 错误写法:
new CustomEvent('editor:change', { detail: 'text' })、{ detail: null }、{ detail: document.body } - 正确结构至少含
type和payload:{ type: 'insert', payload: { html: '<p>ok</p>' } } - 禁止传函数、
Map、Set、class实例——跨 iframe 会序列化失败,且无法被 JSON 安全克隆 - 监听端必须先判空再解构:
if (e.detail && typeof e.detail === 'object') { const { type, payload } = e.detail; }
dispatchEvent 前必须确认目标元素存在且可访问
常见错误是直接对 document.getElementById('console-log') 调用 dispatchEvent,结果元素还没挂载,或藏在 Shadow DOM 里,调用直接静默失败。
- Light DOM 场景:先查再发,加空值判断:
const el = document.getElementById('console-log'); if (el) el.dispatchEvent(evt); - Shadow DOM 场景:不能用
this.dispatchEvent(evt)(发给自定义元素自身),得明确指向this.shadowRoot.dispatchEvent(evt) - 更稳妥的兜底方案:用全局事件总线,
document.dispatchEvent(evt)广播,再由日志组件在document.addEventListener('log:entry', ...)监听
addEventListener 注册时机和作用域必须匹配事件冒泡路径
“事件发了,但监听没响应”——八成是注册时机或作用域错位。
- 监听器注册太晚:比如在
connectedCallback里加监听,但编辑器初始化阶段已触发首条editor:change,这条就丢了 - 冒泡路径断裂:编辑器在 shadowRoot 内 dispatch,却在
document上监听,且没设bubbles: true→ 事件卡在 shadow boundary - 误用
once: true:只捕获第一次,后续所有变更都失效 - 监听位置要和 dispatch 目标一致:发给
#console-log,就得在它身上监听;发给document,就得在document上监听
data-* 属性命名与读写必须严格遵循规范
看似只是拼写问题,实际会导致 dataset 读不到、状态不一致、JSON 解析崩溃。
- HTML 中命名必须全小写 + 连字符:
data-user-id✅,data-userId❌(element.dataset.userId返回undefined) - JS 中写入必须用
setAttribute:el.setAttribute('data-status', 'loading');el.dataset.status = 'loading'只改代理副本,不更新真实 DOM 属性 -
dataset值永远是字符串:el.dataset.count + 1得到"421",不是43;数值运算前务必Number(el.dataset.count) - 存 JSON 字符串必须手动
JSON.parse,且加 try/catch;服务端输出前需 HTML 实体编码,否则&、'会让JSON.parse()报错
细节堆叠起来才叫规范。比如一个 detail 对象里混进 document.querySelector 返回的节点,或者监听器注册在 DOMContentLoaded 之后却想捕获组件构造阶段的事件——这种组合错误不会报语法错,但会让通信链路在某个环节彻底静默。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











