自定义元素命名必须含连字符且全小写,否则customelements.define()立即抛domexception;constructor仅初始化,dom操作须在connectedcallback中执行;扩展现有标签需用is属性并严格匹配注册名。

自定义元素命名必须含连字符且全小写
浏览器会直接拒绝注册不合规名称,比如 mybutton、MyButton、userprofile,抛出 DOMException: The name "xxx" is not a valid custom element name。这不是警告,是立即失败——customElements.define() 根本不会执行后续逻辑。
必须同时满足两个硬性条件:
- 名称中至少含一个 ASCII 短横线(-),如
date-picker、status-badge - 全部小写,禁止下划线、大写字母、单个单词(
button不合法) - 不能与原生标签重名(
div、slot、template均被拦截)
constructor 只初始化,DOM 操作必须在 connectedCallback
很多人把渲染、事件绑定、this.getAttribute() 全塞进 constructor,结果 this.shadowRoot 是 null,样式不生效,属性读不到——因为此时元素还没挂载到文档,DOM 上下文不存在。
正确分工很明确:
-
constructor:只调super()、创建 Shadow DOM(this.attachShadow({ mode: 'open' }))、声明私有字段 -
connectedCallback:做所有 DOM 查询(this.querySelector())、设置innerHTML、监听事件、手动读取初始属性值(attributeChangedCallback不触发首次赋值) - 如果组件可能多次挂载/卸载(如路由切换),
disconnectedCallback必须清理定时器和事件监听器,否则内存泄漏
扩展现有标签必须用 is 属性且严格匹配注册名
想让 <ul></ul> 支持虚拟滚动?不能写 <virtual-list></virtual-list> 或直接用 <ul></ul>。必须继承 HTMLUListElement,注册时传 { extends: 'ul' },使用时只能写 <ul is="virtual-list"></ul>。
常见错误包括:
-
is值大小写或连字符与customElements.define('virtual-list', ...)第一个参数不一致 → 生命周期钩子完全不触发 - 混用:
<ul is="virtual-list"></ul>和document.createElement('virtual-list')同时存在 → 后者创建的是未知元素,无任何自定义行为 - 漏掉
super()在构造函数第一行 → 实例化时报Failed to construct 'XXX': Please use the 'new' operator,控制台不提示具体位置
富文本编辑器里不能直接用 customElements.define()
在 contenteditable="true" 区域内插入已注册的自定义标签(如 <my-inline-note></my-inline-note>),浏览器不会调用它的 constructor 或 connectedCallback,DOM 节点只是被当作普通未知标签渲染(类似 <xyz></xyz>),shadowRoot 完全不挂载,事件绑定失效,光标还可能卡在边界外。
真正可行的替代方案是:
- 用
<span data-type="note"></span>承载元信息,由编辑器统一管控渲染与交互 -
contenteditable="false"阻止光标进入,避免破坏结构 - 通过 CSS
[data-type]::before或框架组件动态渲染视觉表现 - 序列化时提取
data-*属性生成 JSON,而非依赖 HTML 字符串
独立自定义元素看似自由,但一旦涉及编辑器、表单参与、可访问性等真实场景,约束远比表面多;最容易被忽略的不是语法对错,而是 DOM 构建阶段就决定的原型链不可变性——is 值只在元素创建时生效,之后改它没用。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











