contenteditable必须配tabindex="0"才能键盘聚焦,仅设contenteditable="true"无法Tab进入、违反WCAG 2.1.1;tabindex="-1"仅支持JS聚焦,tabindex正数会破坏阅读顺序;CSS的pointer-events:none或user-select:none也会阻断光标定位。

contenteditable 必须配 tabindex="0" 才能键盘聚焦
写了 contenteditable="true" 却点不进去、Tab 不进去,不是浏览器 bug,是漏了 tabindex="0"。这个组合才是可编辑 + 可聚焦的最小合法单元。
常见错误:
- 只写
contenteditable,元素不可键盘进入,违反 WCAG 2.1.1(键盘可访问性) - 写了
tabindex="-1"—— 可编程聚焦(el.focus()),但无法自然 Tab 进入 - 写了
tabindex="5"—— 强行插入 tab 流,打乱阅读顺序,屏幕阅读器会跳读 - 父级或子级有
pointer-events: none或user-select: none,光标定位失败
实操建议:
- 启用时同步设置:
el.setAttribute('contenteditable', 'true'); el.tabIndex = 0; - 禁用时还原:
el.setAttribute('contenteditable', 'false'); el.tabIndex = -1; - 避免在
<script></script>、<meta>上用contenteditable—— 浏览器静默忽略
data-* 属性命名和取值有硬性规则
data-user-id="123" 写对了,JS 里却拿不到?大概率是 dataset.userId 拼错了大小写或连字符处理方式。
立即学习“前端免费学习笔记(深入)”;
关键限制:
- HTML 中的连字符(-)在 JS 中必须转为驼峰:
data-user-id→dataset.userId,不是dataset.userid或dataset.Userid - 数字开头的属性名(如
data-1st-place)不能用点语法:dataset.1stPlace是非法变量名,必须用dataset["1st-place"] - 属性名只允许 ASCII 字母、数字、
-、_、.;data-user:name会被浏览器直接丢弃 - 值永远是字符串:
data-count="0"→el.dataset.count === "0",需手动Number(el.dataset.count)
注意:框架(React/Vue)不响应 dataset 变更,el.setAttribute('data-id', '500') 不会触发组件重渲染。
hidden 属性对 script/meta 无效
hidden 看似万能隐藏开关,但它在某些元素上根本不起作用 —— 不报错、不警告,只是安静失效。
具体表现:
-
<script hidden></script>和<meta hidden>:DOM 中仍存在,执行逻辑照常,hidden被忽略 -
<style hidden></style>:样式规则依然生效,因为hidden不影响 CSSOM 加载 - 旧版 Safari 对
hidden支持不稳定,建议降级用style.display = 'none'
真正稳定跨元素的显示控制只有:style(内联)、class(配合 CSS)、以及明确语义化的 hidden(仅对常规容器/文本类元素有效)。
id 重复会导致 getElementById 返回第一个匹配项
页面里两个 <div id="modal"></div>,document.getElementById("modal") 总是返回第一个 —— 不报错,但后续操作全错位。
后果不止 JS:
- CSS 的
#modal选择器只命中第一个,样式错乱 - 锚点链接
#modal永远滚动到第一个 - ARIA 关联(如
aria-labelledby="modal")指向错误目标 - HTML 验证器报 warning,但开发者常忽略
规避建议:
- 生成动态 id 时加唯一前缀或时间戳:
id="modal-${Date.now()}" - 用
querySelectorAll('[id="modal"]')检查重复,而非依赖getElementById - 优先用
class或data-做批量标识,id仅用于真正需要唯一引用的场景
全局属性不是“写了就生效”,很多只是存着而已。最易被忽略的是:属性是否被当前元素类型支持、是否被浏览器实际解析、是否与框架的数据响应机制冲突。写之前,先确认它在这个上下文里是不是真能动。



















