应只校验当前 fieldset 内字段:通过 document.queryselector('fieldset.active') 获取当前步骤容器,再用 queryselectorall('input, select, textarea') 遍历其子控件并调用 checkvalidity(),任一失败即返回 false。

为什么 form.checkValidity() 会校验所有步骤
因为浏览器原生的 form.checkValidity() 不管字段是否可见,只要在 <form></form> 内、带 required 或其他验证属性,就会被纳入检查范围。点“下一步”时若没拦截默认行为,它会扫完整个表单——第 2 步的 input[required] 还没显示,却已报错,用户根本不知道哪错了。
怎么只校验当前 fieldset 里的字段
核心是别依赖整个 form,而是聚焦当前语义化步骤容器。用 <fieldset></fieldset> 包裹每步,配合 legend,再用 JS 锁定当前激活的 fieldset:
- 给当前步骤的
<fieldset></fieldset>加 class="active" 或data-step="2" - 用
document.querySelector('fieldset.active')拿到它 - 调
querySelectorAll('input, select, textarea')只取这组内的控件 - 遍历每个
input,调.checkValidity();任一失败就return false
示例函数:
function validateCurrentStep() {
const active = document.querySelector('fieldset.active');
if (!active) return false;
const inputs = active.querySelectorAll('input, select, textarea');
return Array.from(inputs).every(el => el.checkValidity());
}
type="button" 是防止误提交的关键
常见错误:把“下一步”写成 <button>下一步</button>,没设 type。这种按钮默认是 type="submit",一点击就触发表单默认提交,跳转或刷新,JS 步骤逻辑全丢。
- 中间所有按钮必须显式写
type="button" - 仅最后一步的“提交”按钮用
type="submit",且在它的click事件中不调event.preventDefault() - 切换步骤前,先调
validateCurrentStep(),通过才更新 DOM 和sessionStorage
required 属性不能删,但得控制触发时机
required 是语义和无障碍基础,不能为“避免误校验”而移除。真正要做的,是让校验只发生在用户操作当前步时:
- 保持所有字段的
required属性不变(读屏软件靠它知道哪些必填) - 校验时只查当前
fieldset下的字段,不碰别的 - 如果某步字段需动态必填(比如选了“需要发票”才校验税号),用 JS 控制
input.required = true/false,而非删 DOM 或改 class - 别用
form.reportValidity()—— 它会全局弹提示,干扰用户体验
最易忽略的一点:每次切换步骤后,必须把焦点移到当前步第一个可聚焦字段,否则键盘用户会卡在上一步末尾,也影响屏幕阅读器播报上下文。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











