直接给<option>加disabled属性是唯一正确、语义清晰且原生支持的禁用方式;它使选项变灰、不可点击和键盘选中,仍保留在DOM中且不参与表单提交,而readonly对option完全无效。

直接给 <option> 加 disabled 属性,是唯一正确、语义清晰且浏览器原生支持的方式;用 CSS 隐藏、display: none 或 removeChild() 都不是“禁用”,而是移除或伪装。
怎么让 select 中的某几个选项不可选
只需在对应 <option> 标签上添加 disabled 属性:
<select name="plan"> <option value="1">基础版</option> <option value="2" disabled>已停用套餐</option> <option value="3">旗舰版</option> </select>
- 该选项会变灰、无法鼠标点击,也无法通过键盘(方向键/Enter)选中
- 它仍保留在 DOM 中,占据下拉列表位置,不影响其他选项索引
- 表单提交时,
name=value不会包含这个disabled项(哪怕它有value和selected) - 移动端 Safari 对视觉反馈较弱,建议加
style="color: #999;"增强可读性
为什么不能用 readonly 给 option 禁用
readonly 属性对 <select> 和 <option> 完全无效——HTML 规范未定义其行为,所有主流浏览器都会忽略它。
-
<option readonly>xxx</option>→ 浏览器不报错,但用户照常能选中 -
<select readonly><option>A</option></select>→ 同样无效果,下拉框依然可展开、可切换 - 想限制选择,必须用
disabled;想保留值但禁止编辑,应改用<input type="hidden">+ 只读文本展示
JS 动态控制 option.disabled 的坑
用 JavaScript 切换状态时,别碰 setAttribute 或 removeAttribute,直接操作布尔属性才可靠:
立即学习“前端免费学习笔记(深入)”;
- ✅ 正确:
document.querySelector('option[value="2"]').disabled = true; - ✅ 正确:
if (opt.disabled) { ... }—— 返回布尔值,语义明确 - ❌ 错误:
opt.getAttribute('disabled')→ 可能返回""或null,判断模糊 - ❌ 错误:
opt.removeAttribute('disabled')→ 在某些旧版 Safari 或 React/Vue 渲染后,UI 可能不重绘,看起来还是禁用状态 - 注意:设为
false才是启用;只删属性 ≠ 启用,必须显式赋值
最容易被忽略的一点:禁用的 <option> 本身没有焦点能力,但整个 <select> 仍可获得焦点。如果用户 Tab 进来又卡在禁用项上,得手动 select.nextElement.focus() 引导焦点,否则体验会断掉。



















