disabled属性仅对input、textarea、select、button等原生表单控件生效,对div、span等无效;必须直接作用于控件本身,且为布尔属性,仅存在即禁用;javascript需用.disabled=true/false控制,不可用setattribute;disabled字段不参与表单提交,readonly才可提交但不可编辑。

disabled属性只对原生表单控件生效
给 div、span、label 或 p 加 disabled 属性完全无效——浏览器直接忽略,既不灰化,也不阻止点击或 Tab 聚焦。真正支持它的只有:input(含 type="text"、"checkbox"、"radio"、"submit" 等)、textarea、select、button、fieldset、optgroup、option。
常见错误:<label disabled><input></label>——label 本身不响应 disabled,里面的 input 依然可操作;必须直接作用于 input 本体。
disabled是布尔属性,不是字符串开关
disabled 的语义极简:存在即禁用,不存在即启用。它不接受任何值解析,写成 disabled="false"、disabled="0"、disabled="" 都照样禁用,和 disabled 效果一致。
- ✅ 正确写法:
<input type="text" disabled>、<button disabled></button> - ❌ 无效写法:
el.setAttribute('disabled', 'false')—— 这只是加了个无意义的字符串属性,无法启用元素 - ❌ 错误预期:
el.removeAttribute('disabled')虽能临时启用,但在某些旧版 Safari 中,后续再设el.disabled = true可能失效
JavaScript 动态控制必须用 .disabled = boolean
唯一稳定、跨浏览器一致的方式是直接操作 DOM 属性:
inputEl.disabled = true(禁用)inputEl.disabled = false(启用)if (inputEl.disabled) { ... }(判断状态)
这样做与 HTML 声明式写法行为完全一致,且能正确影响表单验证(如 checkValidity())和 FormData 序列化结果。
特别注意:
- 禁用后焦点不会自动移走,用户按 Tab 可能卡在已禁用元素上,应手动调用 nextElement.focus()
- 若该控件之前有 required,禁用后验证会跳过,但缓存状态可能残留;建议禁用后顺带调一次 reportValidity() 清理
- 在 Vue/React 中,仅改 DOM 的 .disabled 不同步响应式状态,下次 re-render 会覆盖;必须同时更新 data 或 state
disabled 和 readonly 的核心区别不能混淆
选错就丢数据:
-
disabled:字段完全被排除在表单数据之外,FormData和序列化结果里都找不到它;元素不可聚焦、不响应事件、不提交值 -
readonly:用户不能编辑,但值照常提交;input和textarea支持,select、checkbox、radio不支持(会被忽略)
典型踩坑场景:登录页把用户名框设成 disabled,结果后端收不到用户名——其实该用 readonly;如果需要“显示但不可改”且必须提交,别硬套 disabled,考虑 readonly 或配合 <input type="hidden"> 传值。
服务端永远不能信任前端的 disabled 状态。绕过只需删掉属性、用 DevTools 修改 DOM,或直接发 POST 请求。权限控制和字段校验必须落在后端,这是底线。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











