只有原生表单控件(如button、input、select、textarea、optgroup、option)原生支持disabled;div、span、p等无效,label本身不支持;disabled使控件不可交互且提交时不发送值,readonly仅限部分input和textarea,可聚焦、可复制、仍提交值。

disabled 属性直接加在表单控件标签里就能禁用,但不是所有元素都支持,加了也不一定真“锁住”交互。
哪些 HTML 元素能用 disabled
只有原生表单控件才原生支持 disabled:比如 <button></button>、<input>(含 type="text"、"checkbox"、"radio" 等)、<select></select>、<textarea></textarea>、<optgroup></optgroup>、<option></option>。
常见误区:
<div>、<code><span></span>、<p></p>加disabled属性完全无效——浏览器忽略,也不触发任何样式或行为变化-
<label></label>本身不支持disabled,即使加了,也不会禁用它关联的控件(得去禁用<input>本体) -
<fieldset></fieldset>支持disabled,且会递归禁用其内部所有可禁用子控件(但注意:嵌套<fieldset></fieldset>时,内层 disabled 不会覆盖外层) -
disabled:控件不可聚焦、不响应点击/键盘事件、提交时**不会发送值**(哪怕有value) -
readonly:仅对<input>(text/search/tel/url/email/number)和<textarea></textarea>有效;用户不能编辑,但能聚焦、能复制内容、提交时**仍会发送值** - 别混用:给
<input type="checkbox">加readonly没效果;给<input type="number">加disabled后,JS 读.value是空字符串,不是原始值 - 设置时用
element.disabled = true(布尔值),不是字符串"true"或"disabled" - 读取时
element.disabled返回布尔值,不是属性是否存在——哪怕 DOM 上没写disabled,JS 读出来也是false - 通过
setAttribute('disabled', '')可以生效,但removeAttribute('disabled')才能真正解除;仅设为''或'false'都没用(HTML 中只要存在该属性,就禁用) - 如果控件是动态插入的(比如 Vue/React 渲染后),确保操作 DOM 时机正确——别在节点还没挂载时就去设
disabled - CSS 中用
:disabled伪类可以自定义样式,但注意:IE9+ 才支持,IE8 只认[disabled]属性选择器 - 屏幕阅读器会播报 “disabled”,但如果你用
div+pointer-events: none模拟禁用,它完全感知不到,对残障用户不友好 - 禁用不等于隐藏:若逻辑上不该出现,优先考虑
display: none或条件渲染;禁用只适用于“可见但暂时不可用”
disabled 和 readonly 到底差在哪
两者视觉上可能相似(比如都变灰),但语义和行为完全不同:
立即学习“前端免费学习笔记(深入)”;
JS 动态控制 disabled 的坑
用 JS 开关 disabled 很常用,但几个细节容易翻车:
禁用状态下的样式与可访问性
浏览器默认会给 disabled 控件加灰度和低透明度,但别依赖这个:
最常被忽略的是表单提交时的值丢失问题——disabled 字段压根不会进 FormData,也不会出现在 form.elements 的提交集合里。需要保留值又不让改?用 readonly,或者提交前用 JS 临时移除 disabled 再恢复。











