最简单禁用表单控件是直接添加 disabled 布尔属性,存在即生效;JS 应统一用 el.disabled = true/false 控制,避免混用 setAttribute;fieldset disabled 可批量禁用子表单元素,但不作用于自定义组件、Shadow DOM 或 Portal 渲染内容;option disabled 仅禁用下拉项,不影响整个 select。

直接写 disabled 属性最简单
HTML 里禁用表单控件,第一反应就是加 disabled 属性。它是个布尔属性,存在即生效,不用赋值:
<input type="text" disabled><select disabled><option>选我</option></select><button disabled>提交</button><textarea disabled></textarea>
注意:disabled="false" 或 disabled="" 都没用——只要属性存在,就禁用。浏览器会自动灰化、阻止聚焦、跳过表单提交。
JS 动态控制必须用 .disabled = true/false
别碰 setAttribute('disabled', '') 或 removeAttribute('disabled'),容易状态错位。统一走 DOM 属性赋值:
- 禁用:
el.disabled = true - 启用:
el.disabled = false - 判断:
if (el.disabled) { ... }
混用会导致“看起来能点,但点不动”:比如先用 setAttribute 加了属性,再用 el.disabled = false,DOM 属性还在,浏览器仍以属性为准。原生表单元素只认这个布尔值。
立即学习“前端免费学习笔记(深入)”;
批量禁用用 <fieldset disabled>
想一次性锁住一整组输入项,<fieldset disabled> 是标准方案:
- 里面所有
<input>、<select>、<textarea>、<button>都继承禁用状态 - 子元素显式设
disabled = false也无效,会被 fieldset 强制覆盖 -
<legend>不受影响,文字可读但点击无效
但要注意:自定义组件(比如 div 模拟的下拉框)、Shadow DOM 内容、或通过 Portal 渲染到 body 的元素,不受 fieldset 控制——它们压根不响应这个继承机制。
禁用选项用 <option disabled>
只让下拉框里的某几项不可选,不是整个 select 冻结:
<option value="old" disabled>已停用套餐</option>- 该选项保留在 DOM 中,视觉灰化,键盘和鼠标都无法选中
- 提交时不会包含这个
name=value对,FormData 里找不到它 - 别误写成
<select disabled>——那是整个控件锁死,连可用项也点不了
移动端 Safari 对 option disabled 的灰度显示较弱,建议加内联样式 style="color: #999;" 补充提示。
真正容易被忽略的不是怎么写代码,而是禁用后是否同步清理交互状态:比如按钮禁用时焦点还停在上面,用户按 Tab 就卡住;或者表单验证通过后没及时 el.disabled = false,导致用户以为功能坏了。



















