CustomStateSet.add() 不存在于 HTML 或 Web Components 标准中,是混淆 ElementInternals.states(只读 set)、第三方库抽象或 CSS :state() 伪类所致;实际状态标记应使用私有属性、dataset、toggleAttribute 或受限的 states.set。

HTML 标准中没有 CustomStateSet 或其 add 方法。这是个常见误解,源于混淆了 Web Components 规范中的几个概念:浏览器原生不提供名为 CustomStateSet 的接口,也不存在直接挂载在自定义元素实例上的 add 方法用于“内部状态标记”。
为什么查不到 CustomStateSet.add()?
这个名称既不在 HTML Living Standard 中,也不在 Custom Elements 或 Shadow DOM 规范里。它可能是对以下某项的误记或拼凑:
-
ElementInternals.states(Chrome 111+ 实验性支持)——返回一个NamedNodeMap类似物,但它是只读的,不支持add(); -
ElementInternals.setFormValue()—— 仅用于表单关联,不管理通用状态; - 第三方库(如 Lit、Stencil)的私有状态管理抽象,非标准 API;
- 把 CSS 的
:state()伪类(尚未被任何浏览器实现)和设想中的 JS 接口混在一起了。
真正可用的自定义元素内部状态标记方式
要为自定义元素打“内部状态标记”,实际可行路径只有几种,取决于用途:
- 用私有实例属性(最常用):
this._isLoaded = true、this._status = 'pending'; - 用
ElementInternals.states(仅 Chromium,需启用 flag):element.internals().states.set('loading', '')—— 但注意它只影响:state(loading)伪类匹配,且目前无 JS 读取接口; - 用
dataset(适合需透出到 DOM 的状态):this.dataset.loading = 'true',然后用[loading]选择器; - 用
toggleAttribute()(语义清晰):this.toggleAttribute('disabled', true),配合:host([disabled])样式。
容易踩的坑:误信实验性 API 文档
某些早期 Chromium 构建版本曾短暂暴露过 ElementInternals.states 的 add() 方法,但它很快被移除,改为只读的 set()。如果你在控制台看到 states.add is not a function,不是你写错了,是规范变了。
立即学习“前端免费学习笔记(深入)”;
- 检查 Chrome 版本 ≥ 111 且启用了
chrome://flags/#enable-experimental-web-platform-features; - 不要依赖
states.keys()或遍历 —— 当前实现不支持; - 服务端渲染或 SSR 场景下,
ElementInternals完全不可用,必须降级到属性/私有字段方案。
真正在用的状态标记,99% 都靠私有属性 + 生命周期方法维护。别在标准文档里找 CustomStateSet,它不存在。



















