disabled属性存在即生效,可禁用表单控件并阻止聚焦、输入和提交;readonly仅禁止编辑但允许聚焦和提交;动态控制应使用element.disabled=true/false而非setattribute;批量禁用推荐fieldset disabled。

直接加 disabled 属性是最可靠的方式
只要在 <input>、<textarea></textarea>、<select></select> 或 <button></button> 上写上 disabled,浏览器就会立刻禁用它:阻止聚焦、拦截所有输入、跳过表单提交。写成 disabled="false" 或 disabled="" 都没区别——属性存在即生效。
常见错误现象:<input disabled> 或 <div disabled><input></div>,前者仍禁用,后者完全无效(disabled 对 <div> 无意义)。
<ul>
<li>
<code><input type="text" disabled> —— 灰掉、不能点、不能 Tab 进去、提交时字段消失
<select disabled></select> —— 下拉箭头不可点,选项无法选<button disabled></button> —— 点击无反应,不触发 click 事件(但监听器仍会执行,只是用户无法原生触发)
disabled 和 readonly 别混用
两者行为差异极大,选错会导致后端收不到值或用户绕过限制:
-
disabled:字段彻底退出表单流程 —— 不聚焦、不提交、不触发input/change,FormData里根本找不到它 -
readonly:只锁编辑,不限制聚焦和提交 —— 用户能 Tab 进去、双击选中、Ctrl+C 复制,值照常发给后端 -
readonly对<select></select>、<input type="checkbox">、<input type="radio">完全无效,写了也白写
典型误用:登录页把用户名 <input> 设为 disabled,结果后端收不到用户名;该用 readonly。
JavaScript 动态控制必须用 .disabled = boolean
别用 setAttribute('disabled', '') 或 removeAttribute('disabled'),尤其在旧版 Safari 或 IE 中容易失效或状态不同步。
- 禁用:
el.disabled = true - 启用:
el.disabled = false - 检查状态:
if (el.disabled) { ... }
容易踩的坑:
- 禁用当前聚焦元素后,焦点不会自动移走,用户按 Tab 可能卡住 —— 建议紧接着调
nextEl.focus() - 在 Vue/React 中,仅改 DOM 的
.disabled不同步响应式状态,下次渲染会被覆盖 —— 必须同时更新data或state - 如果该元素之前有
required,禁用后 HTML5 校验会跳过,但checkValidity()返回值可能残留,建议禁用后顺手调一次reportValidity()
批量禁用优先用 <fieldset disabled></fieldset>
想一次性锁住地址区、权限组或整个步骤区块,把它们包进 <fieldset disabled></fieldset>,比逐个加 disabled 更简洁、语义更准,且浏览器原生递归禁用所有子控件(包括嵌套的 <fieldset></fieldset>)。
注意边界:
-
<legend></legend>文本不受影响,仍可读、可聚焦 —— 别指望它也被“灰掉” - 子元素显式写
disabled="false"也无效,父级fieldset的禁用状态强制覆盖 -
<form></form>标签本身不支持disabled,但用<fieldset disabled></fieldset>包裹就等效实现
真正要小心的是服务端校验 —— 前端禁用纯属用户体验优化,删掉 disabled 属性或直接发请求,后端照样能收到数据。权限逻辑和字段必填判断,必须落在服务端。











