readonly不能阻止所有编辑行为,因为它仅禁用键盘输入和删除,不拦截粘贴、拖拽、js赋值或开发者工具修改;它仅作用于input(文本类)和textarea,对select、button等无效;与disabled的核心区别在于readonly值仍会提交。

readonly 属性为什么不能阻止所有编辑行为
因为 readonly 只禁用键盘输入和删除,不拦截粘贴、拖拽文本、JS 赋值或开发者工具修改。用户右键粘贴、Ctrl+V、甚至用控制台执行 input.value = "new" 都能绕过它。它本质是“视觉+交互层的只读”,不是防护锁。
哪些元素加了 readonly 才真正生效
只有两类元素响应 readonly 属性:
-
<input>:仅限type="text"、"password"、"email"、"tel"、"url"、"search"、"date"等文本类类型;type="checkbox"、"radio"、"file"、"hidden"上设了也无效 -
<textarea></textarea>:完全支持 -
<select></select>、<button></button>、<div contenteditable> 等设 <code>readonly会被浏览器直接忽略,必须换用disabled或 JS 控制逻辑动态设置 readonly 的 JavaScript 写法陷阱
用 JS 切换状态时,常见错误有三个:
- 写成
el.readOnly = false想恢复可编辑——但旧版 Safari 不认这个赋值,应改用el.removeAttribute("readonly") - 设了
readonly却没同步处理tabindex,导致 Tab 键仍能聚焦进去,光标闪烁却无法操作,体验割裂 - 在 React 中写成
readonly={isLocked}—— 正确写法是readOnly={isLocked}(驼峰,拼错就失效)
readonly 和 disabled 混用时最常丢的字段值
表单提交后后端收不到某个字段?先查是不是误用了
disabled。它的行为是硬性排除:new FormData(form)里根本不会包含该字段,query string 也不带,连serializeArray()都跳过它。而readonly字段照常提交——这是两者最不可妥协的区别。如果你需要“显示内容 + 可复制 + 值要传给后端”,只能选
readonly;如果字段只是临时占位、不参与业务流程,才考虑disabled。别让产品说“不让改就行”就直接拍板,得追问一句:“这个值,后端要校验吗?” - 写成










