真正稳定跨元素可用的核心全局属性只有id、class、data-*、title、lang、dir、style、tabindex(需设为"0"才可聚焦);contenteditable在等标签无效,hidden在中被静默忽略。

真正能影响运行时行为的全局属性就那么几个,其余多数只是语法合法但无实际效果——用错一个,getElementById找不到、dataset读不到、焦点流乱序、无障碍直接失效。
哪些全局属性真正在所有元素上生效
不是所有标着“全局”的属性都真正通用。比如contenteditable在<script></script>或<meta>上完全无效;hidden放在里浏览器会静默忽略——不报错,也不起作用。
真正稳定、跨元素可用的核心全局属性只有这几个:id、class、data-*、title、lang、dir、style、tabindex(注意:必须显式设为tabindex="0"才可聚焦)。
-
aria-*系列虽常被归为全局,但必须配合语义角色(如role="button")才生效;单独加aria-label到<div>上,屏幕阅读器大概率跳过 <li> <code>draggable默认是"auto",不是true;图片和链接默认可拖,<p></p>默认不可拖,得显式写draggable="true" -
exportparts只对含 Shadow DOM 的自定义元素有意义,普通页面基本用不到 -
class支持多值,但空格敏感:class="btn primary"和class="btn primary"(两个空格)会被解析为三个类名:["btn", "", "primary"],导致classList.contains("primary")返回false - 用
classList操作比直接改className更安全,例如el.classList.add("active")不会覆盖已有类,而el.className += " active"容易引入多余空格或重复 -
data-后只能跟 ASCII 字母、数字、连字符(-)、点(.)、下划线(_),不能有冒号(:)或空格,data-user:name是无效的,会被浏览器静默忽略 - 值始终是字符串,哪怕写
data-count="0",取出来也是"0",需要手动转类型:Number(el.dataset.count)
id 和 class 在 DOM 操作中的性能与行为差异
id是浏览器内部哈希索引,document.getElementById("x")是O(1)查找;而class依赖CSS选择器引擎,document.querySelector(".x")或document.getElementsByClassName("x")都要遍历匹配,尤其在深层嵌套或大量节点时有感知延迟。
一个页面中id值重复,getElementById只返回第一个匹配项,HTML验证器会警告,但JS不报错。
data-* 属性读写时的命名陷阱
HTML中写data-user-id="123",JS里访问的是dataset.userId(连字符变驼峰,首字母小写),不是dataset.userid或dataset.Userid。大小写不匹配就拿不到值。
如果属性名含数字开头,比如data-1st-place,JS中无法通过dataset.1stPlace访问(变量名非法),得用dataset["1st-place"]。
hidden 属性与 display: none 的行为区别
hidden是布尔属性,只要存在就生效,值无关——写成hidden="false"依然隐藏;display: none是CSS声明,受层叠和优先级影响。
hidden="until-found"对应content-visibility: hidden,元素仍参与布局;而hidden(无值)等价于display: none,不参与布局,内外边距等也不占空间。
动态控制显示/隐藏时,别混用:el.hidden = false不会让display: none失效,反之亦然——它们是两条独立路径。











