要关闭 checkvalidity() 触发的默认校验,需移除 required 等校验属性或设 setcustomvalidity('');提交时禁用原生校验须用 novalidate 属性而非 preventdefault()。

怎么关掉 checkValidity() 触发的默认校验
HTML5 表单验证不是“开了就能关”的开关,而是靠绕过触发时机来实现“免校验”。checkValidity() 本身是只读检查函数,它不提交、不阻止行为,但会强制执行所有内置校验规则(比如 required、type="email")。如果你在 API 调用前手动调了它,又不想让它弹出错误提示或返回 false,唯一可靠办法是提前把校验逻辑卸载掉。
- 移除表单控件上的
required、pattern、min/max等校验属性(最彻底) - 临时设
element.setCustomValidity('')清空自定义错误(对已触发过校验的元素有效) - 避免在监听
submit之外的地方主动调checkValidity()—— 很多人在fetch前加这句,结果反而暴露了隐藏校验
submit 事件里怎么跳过浏览器原生校验
表单提交时浏览器自动校验,不是靠 JS 控制的,而是由 form 元素的 novalidate 属性决定。这个属性一开,整个表单所有控件的原生校验(包括红色边框、tooltip 提示、submit 阻断)全部失效。
- 写死:
<form novalidate></form>—— 最简单,适合纯 API 提交场景 - 动态加:
formElement.setAttribute('novalidate', '')—— 注意不是设成'false',布尔属性存在即生效 - 别混淆:
form.noValidate = true是 JS 属性,效果等同于novalidate属性,但 DOM 上看不到,调试时容易漏看
为什么 event.preventDefault() 不等于禁用校验
很多人以为在 submit 回调里写了 event.preventDefault() 就万事大吉,其实不是。浏览器在校验阶段就决定了是否允许进入 submit 事件:如果字段不合法,连事件都不会触发;只有校验通过后,才会派发 submit 事件并默认刷新页面。所以 preventDefault() 只管“不跳转”,不管“不校验”。
- 现象:输入空邮箱,点提交,没弹提示也没进
submit回调 → 校验失败被拦在事件外 - 验证方式:在
form上监听invalid事件,能捕获到被拦下的非法输入 - 真正要做的:要么提前关校验(
novalidate),要么确保输入始终合法(比如用inputmode+ 后端兜底)
reportValidity() 和 checkValidity() 的实际差异
这两个函数都走校验流程,但行为完全不同:checkValidity() 只返回 true/false,不打扰用户;reportValidity() 除了返回值,还会主动触发 UI 提示(红边框、气泡、焦点滚动)。API 调用前如果误用了后者,用户会看到突兀的报错,哪怕你马上发请求也掩盖不了。
立即学习“前端免费学习笔记(深入)”;
- 常见误用:把
if (!form.reportValidity()) return当成“友好提示”,结果在非提交场景(如保存草稿)里频繁触发 UI 干扰 - 正确做法:仅在明确需要用户感知时(比如点击“提交”按钮)才用
reportValidity();其他时候用checkValidity()或直接关校验 - 兼容注意:
reportValidity()在 Safari 10.1+ 才支持,老版本会静默失败,别依赖它的返回值做逻辑分支
真正难的不是关掉哪个 API,而是搞清校验发生在哪一层:是 HTML 属性层(可删)、事件层(可屏蔽)、还是 JS 调用层(可绕过)。混用 novalidate、setCustomValidity 和 reportValidity 容易互相覆盖,建议选一种主策略,别叠 Buff。











