合法自定义标签名必须同时满足三个条件:至少含一个 ASCII 短横线(如 my-button)、全部小写、不能与原生标签名冲突;缺一不可,浏览器逐项校验。

customElements.define() 报 DOMException: The element name is not valid 怎么办
直接原因是标签名不满足 HTML 规范的硬性校验——不是兼容性问题,也不是浏览器 bug,而是解析器在调用 customElements.define() 时立即拒绝非法名称。
常见非法写法包括:mybutton(缺短横线)、MyButton(含大写字母)、my_button(用下划线)、123abc(纯数字开头)、html 或 slot(与原生保留名冲突)。
- 错误信息固定为:
DOMException: The element name is not valid -
try/catch捕获后无法补救:注册失败即组件未定义,后续document.createElement('mybutton')返回的是HTMLUnknownElement,不触发任何生命周期 - 必须在注册前就确保名称合法,不能靠运行时 fallback
合法自定义标签名必须同时满足哪几个条件
三个条件缺一不可,浏览器逐项校验:
- 至少含一个 ASCII 短横线(
-),如my-button、data-table - 全部小写,不允许出现大写字母或 Unicode 字符(
my-Button、my-按钮都非法) - 不能是已存在的原生标签名(如
div、input、dialog),哪怕加了短横线也建议避开(dialog-overlay可能被未来标准占用)
命名前缀(如 shop-button、abc-modal)纯属团队协作约定,浏览器不识别也不强制;但它能预防 npm 包间名称冲突——两个包都注册 ui-button 会导致后者覆盖前者,且无警告。
立即学习“前端免费学习笔记(深入)”;
constructor 里用错标签名会怎样
不会报错,但根本走不到 constructor。因为 customElements.define('mybutton', MyButton) 这一行就会抛出 DOMException,类定义和 constructor 都不会执行。
也就是说,命名错误发生在注册阶段,早于任何实例化逻辑。你看到的“组件没反应”“点击无效”“样式不生效”,大概率源头就卡在这一步。
- 检查控制台报错,确认是不是
The element name is not valid - 别在
constructor里写this.innerHTML = ''或读取属性——此时元素还没插入 DOM,属性可能为空,但这和命名无关,是另一类常见误用 - 用
document.createElement('my-button')测试前,先确认customElements.get('my-button')是否返回构造函数(返回undefined就说明注册失败)
为什么必须带短横线,而不是用下划线或驼峰
这不是风格偏好,是 HTML 规范层的设计契约:浏览器靠短横线无歧义地区分用户定义元素和未来可能标准化的原生标签。下划线(my_button)在旧版 Safari 中不识别;驼峰(MyButton)会被解析器当作非法字符直接截断或拒绝。
真正要注意的是兼容性断层:比如你在 my-progress 内部用 progress::-webkit-progress-value 是有效的,但写 my-progress::-webkit-inner-spin-button 什么都不会匹配——浏览器根本不认识这个标签名的私有伪元素语义。
短横线是唯一被所有现代浏览器一致支持的分隔符,其他形式没有例外,也没有降级路径。



















