contenteditable 应仅在富文本场景启用,需兼顾可访问性、输入法兼容与 xss 防护;关闭时须移除 tabindex,监听 blur+keydown,输出内容须 html 转义或白名单过滤。

contenteditable="true" 什么时候该用、怎么关
它不是“让 div 可编辑”就完事了,而是要配合可访问性、输入法兼容性和 XSS 防御一起考虑。
常见错误现象:contenteditable 元素在中文输入法下光标跳动、输入延迟;用户粘贴 Word 内容后样式炸裂;点击空白处焦点丢失;input 事件不触发导致保存逻辑漏掉最后一次修改。
- 只在明确需要富文本输入的场景启用,比如笔记卡片正文、评论区富文本框,别给
div或section盲加 - 设为
contenteditable="plaintext-only"可阻止格式粘贴,但会禁用粗体/斜体等原生格式操作,权衡取舍 - 关闭时必须同时移除
tabIndex(设为-1),否则屏幕阅读器仍会把它当作可聚焦项,但无语义 - 捕获内容变更建议监听
blur+keydown(防 Ctrl+Z 后未 blur 就离开),而不是依赖input - 生产环境务必对输出内容做 HTML 转义或白名单过滤,
<script>alert(1)</script>真的能执行
draggable 配 ondragstart 才算真正可用
draggable="true" 只是打开开关,不写 JS 就拖不动,更别说排序或移动了。
使用场景:任务看板列内拖拽排序、表格行重排、文件预览区拖入上传——这些都依赖浏览器原生 drag API,但必须手动补全数据传递和放置许可。
-
ondragstart中必须调用event.dataTransfer.setData('text/plain', 'item-42'),否则目标区域收不到任何数据 - 目标容器要监听
ondragover并立即执行event.preventDefault(),否则浏览器默认阻止 drop - 移动端完全不支持原生 drag 事件,iOS / Android Chrome 均无例外;需 fallback 到
touchstart/touchmove自实现,不能省 - 拖拽过程中浏览器不会自动加
opacity或cursor样式,得自己用 CSS 类控制,例如[draggable]:active { opacity: .7; }
enterkeyhint 改的是软键盘回车键文案,不是功能
它只影响虚拟键盘上那个按钮显示什么文字(search / go / next),不改变按下后的实际行为。很多人误以为加了就自动提交表单或跳转,结果发现毫无反应。
适用场景:表单字段聚焦时引导用户预期,尤其在无明确 submit 按钮的单字段页(如搜索页、登录页)。
- 值必须是枚举值:
enter、done、go、next、previous、search、send,其他字符串无效 - 仅在
<input>和<textarea></textarea>上生效,div[contenteditable]不支持 - Safari iOS 支持较好,Android Chrome 从 v100+ 开始稳定支持,旧版本直接忽略该属性
- 别和
onsubmit或formaction混淆——它不触发任何事件,只是提示
hidden="until-found" 的布局行为容易被忽略
hidden 默认等价于 display: none,但加了 until-found 就完全不同:它保留布局空间,只是内容不可见,直到被辅助技术“发现”才渲染。
这个值专为可访问性设计,不是为了视觉隐藏,也不是懒加载替代方案。
-
hidden="until-found"触发的是content-visibility: hidden,元素仍参与文档流,内外边距、高度都保留 - 它不会阻止 JS 访问或 DOM 操作,
el.hidden读出来仍是true,但getBoundingClientRect()有值 - 搜索引擎和屏幕阅读器在初始解析时跳过该元素,直到用户导航到它(如通过 Tab 进入或 aria-controls 关联)才加载内容
- 别用它代替
display: none做条件渲染,也别指望它提升首屏性能——它不阻塞资源加载,也不延迟 JS 执行
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











