id是o(1)哈希查找,class需遍历匹配;重复id导致getelementbyid只返首个;classlist操作比改classname更安全;data-*属性名转驼峰且值恒为字符串;hidden不等价于display:none,影响无障碍。

真正能提升前端代码效率的 HTML 全局属性,不是用得越多越好,而是选对、用准、避坑。
id 和 class 在 DOM 查找与样式中的性能差异
id 是浏览器内部哈希索引,document.getElementById("x") 是 O(1) 查找;class 依赖 CSS 选择器引擎,document.querySelector(".x") 或 document.getElementsByClassName("x") 都要遍历匹配,尤其在深层嵌套或大量节点时有感知延迟。
- 一个页面中
id值重复,getElementById只返回第一个匹配项,HTML 验证器会警告,但 JS 不报错 -
class支持多值,但空格敏感:class="btn primary"和class="btn primary"(两个空格)会被解析为三个类名:["btn", "", "primary"],导致classList.contains("primary")返回false - 用
classList.add("active")比直接改className += " active"更安全,后者容易引入多余空格或重复
data-* 属性读写时的命名与类型陷阱
HTML 中写 data-user-id="123",JS 里访问的是 dataset.userId(连字符变驼峰,首字母小写),不是 dataset.userid 或 dataset.Userid。大小写不匹配就拿不到值。
- 如果属性名含数字开头,比如
data-1st-place,JS 中无法通过dataset.1stPlace访问(变量名非法),得用dataset["1st-place"] -
data-后只能跟 ASCII 字母、数字、连字符(-)、点(.)、下划线(_),不能有冒号(:)或空格,data-user:name是无效的,会被浏览器静默忽略 - 值始终是字符串,哪怕写
data-count="0",取出来也是"0",需要手动转类型:Number(el.dataset.count)
hidden 属性与 display: none 的行为区别
hidden 是布尔属性,写成 hidden 或 hidden="" 即隐藏元素,语义上表示“此内容当前不应被呈现”,等效于 display: none,但关键区别在于:它不影响可聚焦性逻辑——若同时设了 tabindex="0",该元素仍能被键盘聚焦,只是不可见。
- 滥用
hidden替代逻辑卸载(如 React 中的条件渲染),会导致无意义的可聚焦元素,破坏无障碍体验 -
hidden放在里浏览器会静默忽略——不报错,也不起作用 - 对
<script></script>或<meta>使用contenteditable完全无效,但不会报错;这类误用只有运行时调试才能发现
lang、dir、title 等语义属性的实际影响点
lang 不仅影响 SEO,还决定拼写检查、语音合成停顿、标点符号渲染(如中文引号 vs 英文引号),dir="rtl" 会改变表单控件内部文本方向,但不会自动翻转按钮布局——需配合 CSS text-align 或 flex-direction 手动调整。
-
title在鼠标悬停时显示工具提示,但屏幕阅读器支持弱,且移动端基本不触发;它不能替代<label></label>或 ARIA 标签 -
translate="no"对品牌词、代码片段、URL 路径有效,但对内联<code>块不起作用——翻译工具通常忽略该标签本身,需包裹在<span translate="no"></span>中 -
tabindex必须显式设为tabindex="0"才可聚焦;设为tabindex="-1"仅支持 JS 主动聚焦(el.focus()),不进入 Tab 流
最常被忽略的是:全局属性不是“通用”就等于“安全”,很多属性在特定上下文中失效或产生副作用,比如 draggable 默认是 "auto",不是 true;aria- 系列必须配合 role 才生效——单独加 aria-label 到 <div> 上,屏幕阅读器大概率跳过。</div>
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











