customElements.define()报“The element name is not valid”需立即检查标签名是否含破折号、全小写且不以破折号开头/结尾,如my-button合法,mybutton、MyButton、my_button均非法;注册须在DOM就绪后且元素实例化前完成。

多团队共用一套 HTML 基础设施时,样式冲突、事件误收、data-* 语义混乱不是“可能出问题”,而是上线后必现的线上故障。核心解法不是靠人盯人,而是靠命名空间 + 注册时机 + 属性契约这三道硬隔离。
customElements.define() 报 DOMException: The element name is not valid 怎么办
这是浏览器强制拦截,不是兼容性问题——HTML 规范要求自定义元素名必须含破折号。注册失败时别查 polyfill 或版本,先看名字。
- 合法写法:
my-button、shop-product-card、abc-modal - 非法写法:
mybutton(缺破折号)、MyButton(大写)、my_button(下划线) - 注册必须在该标签首次出现在 DOM 前完成;若已渲染,需手动调用
customElements.upgrade(el)
class 和 id 名撞车了,BEM 怎么落地才不形同虚设
BEM 不是命名风格偏好,是隔离边界。泛化名如 btn、modal 在多团队场景下等于没隔离。
- 根 block 必须唯一且带业务上下文:
user-profile,不是profile - 子元素严格双下划线:
user-profile__avatar,不写成user-profile-avatar(易与其它连字符命名混淆) - 状态修饰符用双短横:
user-profile--loading,避免is-loading这类无归属的状态名 - 禁止用样式描述命名:
big-red-text随主题变更即失效;user-profile__heading才可持续
data-* 属性为什么写了等于没写
裸名 data-id="123" 是前端与后端之间的无效契约。三个月后没人能确定这是用户 ID、SKU 还是订单号。
立即学习“前端免费学习笔记(深入)”;
- 必须携带业务上下文:
data-user-id="123"、data-api-source="user/profile"、data-user-status="active" - JS 中读取时自动转驼峰:
el.dataset.userId对应data-user-id,但前提是命名本身有意义 - 禁止单 key 存对象:
data-state='{"a":1,"b":2}'会引发竞态更新风险,拆成多个带前缀的字段更安全 - 配合
stylelint的selector-attribute-pattern规则,拒绝不含业务前缀的data-*
事件监听器互相污染,怎么防
组件发 new CustomEvent("submit"),其他任意组件监听同名事件就会误收;挂 window.initWidget 也可能被覆盖。
- 事件类型加组件标识前缀:
shop-product-card:submit、abc-modal:close - 全局变量统一加前缀:
window.abcModalConfig、window.shopProductApi - 避免使用原生事件名(如
click、submit)作为自定义事件类型,防止和原生行为混用
最常被忽略的其实是注册时机和 data-* 的语义绑定——它们不写在规范文档里最显眼的位置,却在联调当天第一个小时就决定是否要通宵改名。



















