HTML 表单约束验证怎么用:required 和 pattern 入门指南
结论:HTML 原生表单校验只需要两个属性——required 负责「不能为空」,pattern 负责「必须长成这个样子」;pattern 是整串匹配,浏览器自动帮你加了 ^(?:…)$,所以你不用写 ^ 和 $,也不能带 /…/ 定界符和 i 标志。想拦截提交、替换提示文案,用 checkValidity() 和 setCustomValidity() 就够了,不需要引第三方校验库。
required 怎么用?它到底把什么算作「空」?
结论:required 判定的是「值的字符串长度为 0」,输入一个空格不算空。
<input required>值必须非空字符串,否则validity.valueMissing === true,提交被浏览器拦下。<input type="checkbox" required>表示必须勾选;type="radio"是同一name组里至少选中一个。<select required>的value为""的选项(比如<option value="">请选择</option>)视为空。type="hidden"不参与约束验证,加required无效。
所以在只判空不够、要拒绝纯空白时,得自己补一句 pattern=".*\S.*"——\S 表示任意非空白字符,只有当整个值里至少有一个非空白字符时才通过。
pattern 的正则怎么写?为什么我写的匹配不上?
结论:pattern 的值是「正则源码片段」,整体必须完整匹配,且不能用标志位。
<input name="user" required pattern="[a-zA-Z0-9_]{3,16}"
title="3-16 位字母、数字或下划线">
<input name="phone" required pattern="1[3-9]\d{9}" title="11 位手机号">
三条硬规则:
pattern="\d{6}"表示整个值恰好 6 位数字。写\d{6}时1234567不通过,因为要求整串匹配。- 不能写
pattern="/\d{6}/i"。要忽略大小写就写字符类[a-zA-Z],没有i标志可加。 - HTML 属性里的反斜杠不经过 JS 字符串转义,写成
\d就是\d,不要写\\d。
浏览器用 v 标志编译 pattern(早期版本用 u),字符类里的 - ( ) [ ] { } / | 建议加反斜杠转义。无效正则会被直接忽略,该字段永远校验通过,这是最常见的「我明明写了 pattern 却没用」的原因。
另外:pattern 只属于 <input>,<textarea> 不支持,得靠 JS 自己判。
怎么用 JS 拿校验结果、改默认提示?
结论:checkValidity() 返回布尔值且会触发 invalid 事件,reportValidity() 还会弹出浏览器气泡,validity 对象告诉你到底错在哪。
const input = document.querySelector('#code');
input.checkValidity(); // false,不弹提示
input.reportValidity(); // false,同时弹气泡
input.validity.valueMissing; // required 没过
input.validity.patternMismatch; // pattern 没过
input.validity.valid; // 全部通过时为 true
input.validationMessage; // 浏览器生成的提示文案
// 换成自己的文案
input.addEventListener('input', () => {
input.setCustomValidity(
input.validity.patternMismatch ? '只能填 3-16 位字母、数字或下划线' : ''
);
});
关键点:setCustomValidity() 传入非空字符串会让该控件永远校验失败,所以必须在值变化时清空。表单级用 form.checkValidity(),form.noValidate = true 或给 <form novalidate> 可关掉原生校验。
还有个容易漏的:校验不通过时 submit 事件根本不会触发,浏览器先拦下了;而 form.submit() 会绕过校验也不触发 submit,要手动验证请用 form.requestSubmit()。
为什么 :invalid 样式一进页面就红了?
结论:required 的空输入框从页面加载那一刻起就是 :invalid,不是用户操作后才变红。
这是规范行为,input:invalid { border-color: red } 会导致一打开表单满屏红框。两种解法:
- 用
:user-invalid,只在用户交互过且不合格时命中,Chrome 119+、Firefox 88+、Safari 16.5+ 已支持; - 或者用 JS 在首次
blur或提交时给元素加.touched类,再写.touched:invalid { … }。
顺带记一下:minlength 只在用户输入过的值上生效,用 JS 直接赋值不算;title 属性的文本会被浏览器拼进默认提示气泡里,等于白送一个低成本的自定义提示位。
一句话收束:判空用 required(注意空格不算空),判格式用整串匹配的 pattern(注意无效正则会被静默忽略),拿结果和改文案用 checkValidity() 与 setCustomValidity(),样式用 :user-invalid 避免一进页面就飘红。
原文链接:https://www.gj0.com/thread-721.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。