readonly字段值会提交,disabled则完全过滤;前者可聚焦复制,后者不可交互且变灰;select等元素不支持readonly,需用替代方案。

readonly 和 disabled 都能让用户无法编辑 <input>,但它们不是可互换的开关——选错一个,后端收不到值、焦点行为异常、甚至表单重置出 bug。
为什么直接写 readonly 有时没反应?
常见原因不是语法错,而是被覆盖或误用:
- 在 Vue/React 中写了
readonly(小写),但框架要求的是readOnly(驼峰);写成readonly="false"依然生效——只要属性存在就只读 - JS 动态设置了
input.readonly = false,但这是无效写法;正确做法是input.removeAttribute('readonly') - CSS 加了
pointer-events: none或user-select: none,看起来不能点、不能选,但原生readonly没生效,用户仍可通过键盘粘贴或脚本改值 -
type="hidden"上加readonly没意义,它本来就不允许交互
readonly 和 disabled 提交时到底差在哪?
这个区别直接影响后端能否收到字段值:
-
readonly字段的value会随表单一起提交,且能获得焦点、响应click/focus,也能监听input事件(只是用户输不进去) -
disabled字段的value**完全不参与提交**,也无法聚焦,所有事件监听器都不会触发 - 表单调用
reset()时:readonly字段会恢复为初始value;disabled字段保持当前值不变
如何用 JS 安全地切换只读状态?
别依赖字符串赋值,优先走 DOM API:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
立即学习“前端免费学习笔记(深入)”;
- 启用只读:
inputEl.setAttribute('readonly', 'readonly')或inputEl.readOnly = true(注意大小写,IE8+ 支持) - 关闭只读:
inputEl.removeAttribute('readonly'),不是设成false或空字符串 - 禁用/启用:
inputEl.disabled = true或inputEl.removeAttribute('disabled') - 检查状态别用
getAttribute('readonly'),而用inputEl.readOnly(返回布尔值)
select 元素没有 readonly 怎么办?
<select></select> 原生不支持 readonly 属性,强行加无效。只能用 disabled,但它会导致值不提交:
- 方案一:提交前用 JS 手动取值,拼进 FormData 或请求体里
- 方案二:用
<div contenteditable="false"> 模拟只读下拉展示,再配隐藏 <code><input type="hidden">存真实值 - 方案三:CSS 锁定交互(
pointer-events: none+user-select: none),但必须搭配服务端校验——因为 JS 仍可绕过
最常被忽略的是:只读不等于不可变。无论 readonly 还是 disabled,都防不住脚本修改;真正需要锁定语义,得靠后端校验 + 初始值比对,而不是前端属性。


















