原生校验需用 required 和 type 基础约束,但易被空格等绕过;应配合 pattern、checkvalidity()、reportvalidity() 和 setcustomvalidity() 实现精准可控的校验逻辑。

用 required 和 type 属性做基础校验
浏览器原生支持的校验最轻量,也最容易被忽略其限制。比如 <input required> 会阻止空提交,<input type="email"> 会检查格式是否像邮箱——但注意,它只校验是否含 @ 和域名结构,不验证邮箱真实存在。
常见错误是以为加了 required 就万事大吉,结果用户输入空格、换行符或全角空格也能绕过。建议配合 pattern 或 JS 进一步约束:
-
pattern要写正则,且必须匹配整个值(隐式加 ^$),例如pattern="[a-z]{3,}"表示至少 3 个小写字母 -
title属性可自定义提示文字,否则浏览器默认提示语可能不友好(如 “请填写此字段”) - 所有原生校验仅在
submit触发时生效,click或change不触发
用 checkValidity() 和 reportValidity() 主动控制校验时机
当需要在按钮点击、离开焦点或异步操作后手动触发校验时,不能只靠 submit 事件。这两个方法是关键入口:
-
checkValidity()返回布尔值,只检测不报错,适合静默判断 -
reportValidity()返回布尔值,同时显示浏览器默认提示气泡,适合用户交互场景 - 对整个表单调用时,任一字段失败即返回
false;对单个元素调用,则只检查该字段 - 注意:如果字段被设为
disabled,它会被跳过校验,即使有required
示例:
document.getElementById('myForm').addEventListener('submit', e => {
if (!e.target.checkValidity()) {
e.preventDefault(); // 阻止提交
}
});
用 setCustomValidity() 替换默认错误信息
原生提示语无法本地化,也无法表达业务逻辑错误(比如“用户名已被注册”)。这时要用 setCustomValidity():
- 传入非空字符串表示校验失败,字符串即为错误提示;传入空字符串表示通过
- 必须在每次校验前重置,否则上次失败状态会残留(常见坑!)
- 和
reportValidity()配合使用效果最好,单独调用不触发 UI 提示 - 不要在
input事件里频繁调用,避免过度重绘;推荐在blur或提交前集中校验
示例:
const userField = document.getElementById('username');
userField.addEventListener('blur', () => {
userField.setCustomValidity(''); // 先清空
if (userField.value.length
<h3>避免混淆 <code>submit</code> 事件与 <code>click</code> 事件的校验时机</h3>
<p>很多人把校验逻辑绑在按钮 <code>click</code> 上,结果发现按回车提交时校验没执行——因为回车触发的是表单的 <code>submit</code>,不是按钮的 <code>click</code>。</p>
- 校验逻辑必须绑定在
form元素的submit事件上,这是唯一可靠入口 - 按钮
click中调用e.preventDefault()无法阻止回车提交 - 如果用了
event.preventDefault(),记得后续手动调用form.submit()完成真实提交(尤其在 AJAX 场景下) - 注意:
submit事件在原生校验通过后才触发;若想绕过原生校验(比如兼容旧浏览器),需提前e.preventDefault()
真正容易被忽略的是:原生校验和自定义校验共存时,reportValidity() 会优先展示原生错误(如 required),只有全部原生通过后,才会显示 setCustomValidity() 设置的内容。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











