checkValidity()仅返回布尔值并触发验证但不阻止提交,需配合preventDefault();reportValidity()更实用,强制显示提示且兼容性好;须用setCustomValidity()注入自定义规则,每次输入前需清空错误消息。

表单提交前用 checkValidity() 触发原生验证
浏览器内置的 required、type="email"、pattern 等属性不会自动在用户输入时生效,必须显式调用验证方法才能触发提示。直接调用 form.checkValidity() 会触发所有字段的原生校验,并显示默认气泡提示(如“请填写此字段”)。
但注意:该方法只返回布尔值,不阻止提交;若要阻止,需配合 event.preventDefault():
form.addEventListener('submit', (e) => {
if (!form.checkValidity()) {
e.preventDefault();
}
});
- 仅对带
name属性的表单控件生效(✅,❌) - 某些旧版 Safari 对
checkValidity()的气泡定位支持不稳定,建议搭配reportValidity()替代(见下节) - 调用后若字段已失效(
input.validity.valid === false),再次调用不会重复弹出提示
用 reportValidity() 替代 checkValidity() 强制显示错误提示
reportValidity() 是更实用的选择:它不仅返回布尔值,还会强制触发并显示浏览器默认的错误消息气泡,且兼容性已覆盖 Chrome 56+、Firefox 53+、Safari 10.1+。
常见误用是把它放在输入事件里频繁调用,导致提示狂闪。正确做法是只在关键节点触发:
立即学习“Java免费学习笔记(深入)”;
原生js表单提交验证代码下载。原生JavaScript实现,适合新手学习js。用户填写完成后,点击提交按钮,判断填写的信息是否符合要求,如不符合将弹出相应的修改信息要求,引导用户正确填写表单。
- 用户点击提交按钮时(最稳妥)
- 离开某个必填字段后(
blur),但需加防抖(如 300ms 延迟)避免干扰输入 - 不建议在
input实时监听中调用——用户还没输完,“邮箱格式错误”的提示就弹出来了
示例:
submitBtn.addEventListener('click', () => {
if (!form.reportValidity()) {
// 至少有一个字段未通过验证,浏览器已显示提示
// 此处可聚焦第一个无效字段:form.querySelector(':invalid')?.focus();
}
});
监听 :valid 和 :invalid 伪类做样式反馈
原生验证结果会实时反映在 DOM 上:input:valid 或 input:invalid 可用于 CSS 样式控制,比手动维护 is-valid 类更轻量、更可靠。
- CSS 中直接写
input:invalid { border-color: #e53e3e; }即可,无需 JS 监听 - 注意:初始加载时,空的
required输入框默认为:invalid,可能造成首屏红边;可用:user-invalid(Chrome 107+、Safari 16.4+)规避,但兼容性有限 - 若需兼容老浏览器,可退化为监听
input+blur后设置自定义 class,但必须同步更新validity状态,否则样式与实际验证结果脱节
自定义验证逻辑必须通过 setCustomValidity() 注入
当需要检查「两次输入密码是否一致」「用户名是否已被注册」这类无法用 HTML 属性表达的规则时,不能只靠 JS 判断布尔值,必须调用 input.setCustomValidity(message) 才能让 checkValidity() 和 reportValidity() 生效。
- 传空字符串
setCustomValidity('')表示通过;传非空字符串表示失败,且该字符串会作为错误提示内容 - 每次输入都应重置:比如在确认密码框中,应在
input事件里先调用confirmInput.setCustomValidity(''),再根据比对结果决定是否设错 - 若忘记清空,上次的错误消息会一直残留,导致
reportValidity()总是报错
示例:
confirmInput.addEventListener('input', () => {
confirmInput.setCustomValidity('');
if (confirmInput.value !== passwordInput.value) {
confirmInput.setCustomValidity('两次输入的密码不一致');
}
});
原生验证链路(HTML 属性 → setCustomValidity → reportValidity)看似简单,但各环节状态不同步是绝大多数表单验证 bug 的根源。尤其 setCustomValidity 的副作用容易被忽略——它一旦设错,不主动清空就会卡死整个验证流程。









