readonly的textarea值会提交,disabled的不会;前者可聚焦复制,后者完全禁用交互;select等控件不支持readonly,contenteditable需设为false才生效。

textarea readonly 和 disabled 的提交行为差异
只读(readonly)和禁用(disabled)最根本的区别在于:前者值会随表单一起提交,后者不会。哪怕你在 JS 里给 disabled 的 <textarea></textarea> 设置了 value,提交时这个字段压根不会出现在 FormData 或 query string 中。
常见错误现象:
后端收不到字段,排查发现前端写了 disabled,但业务逻辑本意是“展示+保留提交”。这时改用 readonly 就能立刻修复。
-
readonly:适合订单号、用户昵称、预填不可改的说明文案等需展示且需提交的场景 -
disabled:适合临时锁定整个表单流程(如等待校验完成),或配合<input type="hidden">补值 - 若必须视觉灰化 + 提交值,别硬用
disabled,而是readonly加 CSS:textarea[readonly] { background-color: #f5f5f5; color: #666; }
textarea 只读状态下仍可聚焦、复制、全选
readonly 的 <textarea></textarea> 不会阻断键盘和鼠标交互——它只是禁止编辑。用户仍能 Tab 进入、Ctrl+A 全选、Ctrl+C 复制,这对查看长文本(如日志、备注)很关键。
而 disabled 会彻底切断这些能力:无法获得焦点、.focus() 调用静默失败、select() 无效、copy 事件不触发。
- 无障碍方面:
readonly元素会被屏幕阅读器读出;disabled元素常被跳过 - JS 判断状态时,用
el.readOnly(注意大小写),不是getAttribute('readonly')—— 后者返回字符串或null,不可靠 - 动态切换时,设只读推荐:
el.setAttribute('readonly', '');取消只读用:el.removeAttribute('readonly')
textarea 不支持 readonly 的常见误写
虽然 <textarea></textarea> 原生支持 readonly,但很多人在框架中写错属性名或混淆语义:
- React 中必须写
readOnly={true}(驼峰),写成readonly={true}会被当字符串 prop,浏览器误判为存在即真 - Vue 模板中
:readonly="true"没问题,但若绑定到<select readonly></select>就完全无效——select不支持readonly,只能用disabled或 JS 模拟 - 某些 UI 库(如 Ant Design)把
readOnly属性映射为 HTMLreadonly,但文档没强调它不影响提交——结果测试发现后端少收一个字段 - 千万别同时写
readonly和disabled:disabled优先级更高,readonly形同虚设,还掩盖真实意图
contenteditable 区域不能用 readonly 或 disabled
如果页面里是 <div contenteditable="true"> 这类富文本容器,<code>readonly 和 disabled 都不起作用。它们只对原生表单控件生效。
真正有效的锁法只有:contenteditable="false"。仅靠 pointer-events: none 或 user-select: none 是不够的——粘贴、回车、格式快捷键依然能触发编辑。
- 动态控制时,直接改属性:
el.contentEditable = 'false'(注意大小写和字符串值) - 移除
contenteditable属性也等效于false,但显式设为false更清晰 - 若需保留样式但禁用编辑,别用遮罩层或透明 overlay——键盘事件仍会穿透
readonly 对 <textarea></textarea> 有效,但对 <select></select>、<input type="checkbox"> 无效;而 disabled 虽然通用,却会抹掉提交值。选哪个,取决于你到底想“锁住输入”还是“锁住提交”。











