先记住这个答案
在 <fieldset> 上设置 disabled,可以一次禁用它包含的后代表单控件。它们不能正常聚焦或修改,提交时也不会作为成功控件出现。第一个 <legend> 内的控件例外,这使得“整组尚未启用”的设置面板可以把启用开关放在组标题里。
disabled会批量禁用后代控件- 第一个
<legend>内控件是例外 - 禁用值不参与普通表单提交
disabled与readonly行为不同
一组设置怎样一起关掉
例如配送地址只有勾选“填写新地址”后才需要编辑。把地址字段包在 <fieldset> 内,直接切换它的 disabled 属性,比逐个切换几十个输入更可靠。组内当前显示的旧值不会因为禁用就从 DOM 消失,但提交表单时不能指望收到这些值。
<fieldset disabled>
<legend><label><input type="checkbox" name="enable">填写新地址</label></legend>
<label for="street">街道</label>
<input id="street" name="street">
</fieldset>首个 <legend> 里的复选框仍可操作。实际页面需要脚本监听它的变化,切换 fieldset.disabled;这里只展示可操作例外的位置。如果把开关移到普通后代区域,它也会随整组被禁用,用户无法自己打开。
禁用不等于只读
readonly 用在支持它的文本类控件上,表示不能编辑,但值通常仍参加提交且可以获得焦点。disabled 则阻止交互并让控件不进入普通提交数据。需要展示一个不可修改但仍要提交的订单编号,应先考虑是否真的需要客户端重复提交;服务端不能信任浏览器回传的隐藏或只读值。
禁用字段不参与约束校验。因此把必填字段禁用后,浏览器不会因为它为空而阻止表单。重新启用时则应重新检查有效性,避免用户以为“灰掉”意味着服务器也不需要这些信息。
还要分清“看起来是灰色”和“实际被禁用”。只给组内控件加一个灰色 CSS 类不会改变它们的焦点、校验和提交行为;fieldset.disabled = true 才会让浏览器按禁用规则处理。若后端编辑页面希望保留旧值,不应依赖这些禁用字段回传,可由服务端保留原记录,或者使用适合的只读展示方式。解除禁用后,原来带 required 的字段会重新参加约束校验。
容易答错的地方
- 认为禁用字段会带着旧值提交
- 表单构造数据时禁用控件不属于成功控件;服务端应有明确默认值或沿用策略。
- 把启用开关放在普通后代里
- 它也会被禁用,用户不能通过这个开关解除整组禁用。
面试官还会怎么问?
为什么第一个 legend 里的输入仍能点?
禁用分组对首个组名内部的表单控件有明确例外,可用作解锁入口。
禁用的 required 输入会拦住提交吗?
不会按普通启用控件参加约束校验;重新启用后才需要满足必填条件。
只读字段与禁用字段提交行为一样吗?
不一样。只读字段通常仍可提交,禁用字段不会进入普通表单数据。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。