真正稳定跨所有元素起作用的全局属性只有id、class、data-*、title、lang、dir、style、tabindex;contenteditable、draggable、hidden在和上完全失效,浏览器静默忽略。

真正能稳定跨所有元素起作用的全局属性,其实就那么几个;其余多数要么受限于元素类型,要么依赖运行时环境,盲目套用反而导致行为不一致。
哪些全局属性在 <script></script> 和 <meta> 上完全失效
像 contenteditable、draggable、hidden 这类看似“通用”的属性,在 <script></script> 或 <meta> 标签上写上去,浏览器会静默忽略——既不报错,也不生效。这不是兼容性问题,而是规范明确禁止:这些元素没有渲染树节点,无法参与交互或布局。
-
contenteditable只对可渲染、可聚焦的容器有效(如<div>、<code><p></p>),对<script></script>无意义 -
hidden对<meta>无效,但不会触发警告;它只影响渲染层,而<meta>本就不渲染 -
tabindex在<script></script>上设为"0"也不会让它进入 Tab 流,因为该元素不可聚焦 - 连字符自动转驼峰,但首字母必须小写:
data-user-id→dataset.userId,不是dataset.Userid - 含数字开头的名,如
data-1st-place,不能用点号访问:dataset.1stPlace是语法错误,得用dataset["1st-place"] - 值永远是字符串:
data-count="0"取出来是"0",Boolean(el.dataset.count)会是true,别直接当布尔用 - 非法字符(如冒号、空格)会被浏览器直接丢弃,
data-user:name等价于没写 -
document.getElementById("x")是哈希查表,O(1),无论 DOM 多深都快 -
document.querySelector(".x")走 CSS 引擎,需遍历匹配;getElementsByClassName("x")返回实时集合,每次访问 length 都可能触发重排 - 重复
id值不会报 JS 错误,但getElementById只返回第一个,且 HTML 验证器会警告 -
class多值空格敏感:class="btn primary"和class="btn primary"(两个空格)解析出的类数组含空字符串,classList.contains("primary")会返回false -
hidden是布尔属性,写hidden、hidden=""、hidden="hidden"效果相同;但它不等价于style="display: none"—— 后者会覆盖所有 display 相关继承 -
hidden不影响盒模型计算(比如父容器仍会为它保留空间?不,它实际也脱离渲染流),但它参与无障碍树的构建逻辑:屏幕阅读器默认跳过hidden元素,而对display: none更彻底地忽略 -
hidden="until-found"是新值,对应content-visibility: hidden,仅在支持该 CSS 属性的浏览器中生效,旧版直接降级为普通hidden
data-* 和 dataset 的命名陷阱与读取失败原因
HTML 写 data-user-id="123",JS 却拿不到 dataset.userId?常见原因不是拼写错,而是命名规则被忽略。
id 和 class 在深层 DOM 中的性能差异
当页面有数千个节点、且频繁调用查找逻辑时,id 和 class 的底层机制差异会变得明显。
hidden 与 display: none 的语义和行为分界点
它们视觉效果一样,但浏览器对待方式不同:一个是声明“这个内容暂时不该被看到”,一个是命令“把它从渲染流里抹掉”。
最易被忽略的其实是语义边界:结构标签(如 <header></header>、<nav></nav>)本身不带行为,加了 onclick 或 role="button" 就等于主动破坏语义。全局属性不是万能胶,而是需要配合元素天然角色使用的信号灯。











