表单约束验证 required pattern
required 负责「不能为空」,pattern 负责「格式必须匹配正则」,两者必须搭配使用:因为 HTML 规范规定空字符串时 pattern 不参与约束验证,只写 pattern 的输入框留空也能提交,拦空值只能靠 required。
required 和 pattern 有什么区别?
结论:required 管「有没有填」,pattern 管「填得对不对」,二者互不替代,也不存在谁包含谁。
required 是布尔属性,加在 input / select / textarea 上,控件值为空字符串时 input.validity.valueMissing === true,校验失败。pattern 接收一个正则字符串,值不匹配时 input.validity.patternMismatch === true。
关键差异在空值处理:值为空串时浏览器跳过 pattern 检查,所以 <input pattern="1[3-9]\d{9}"> 允许用户什么都不填就提交。正确写法是 <input required pattern="1[3-9]\d{9}">。
required 在哪些元素上不生效?
结论:required 对 type 为 hidden、range、color、submit、image、reset、button 的 input 无效,浏览器直接忽略这个属性。
select 的 required 要求选中项的 value 非空,所以必须放一个 <option value="">请选择</option>,否则默认选中第一项非空 option 就永远通过。
同 name 的一组 radio 只需其中一个加 required,组内选中任意一个即整组通过。checkbox 加 required 表示「必须勾选」,常用于同意用户协议场景。
pattern 支持哪些输入类型?正则怎么写?
结论:pattern 只在 text、search、url、tel、email、password 六种类型上生效,number、date、file 上会被忽略。
pattern 的值不要带 /.../ 斜杠,也不要写 ^ $——规范规定它隐式整体匹配,等价于 ^(?:你的正则)$,加锚点属于冗余。pattern 没有 flags 语法,写不了 i 标志,要忽略大小写就写 [a-zA-Z] 或 [Xx]。
pattern 使用 u/v 标志编译,\Z、\- 这类非法转义会编译失败,此时浏览器会忽略整个 pattern,字段直接放行——这是最容易踩的坑。
常用正则直接抄(均已是整体匹配):
手机号 pattern="1[3-9]\d{9}"
6 位邮编 pattern="\d{6}"
18 位身份证 pattern="\d{17}[\dXx]"
密码 8-20 位含字母和数字 pattern="(?=.*[a-zA-Z])(?=.*\d).{8,20}"
还可以配合 title 属性给中文提示,Chrome、Firefox 在 patternMismatch 时会把 title 内容拼接进原生气泡里。
怎么用 JS 手动校验和自定义提示?
结论:checkValidity() 静默校验返回布尔值,reportValidity() 校验并弹出浏览器气泡,setCustomValidity() 覆盖提示文案。
const input = document.querySelector('#phone');
input.addEventListener('input', () => {
input.setCustomValidity(''); // 必须先清空
if (input.validity.patternMismatch) {
input.setCustomValidity('请输入 11 位手机号');
}
});
form.addEventListener('submit', (e) => {
if (!form.checkValidity()) {
e.preventDefault();
form.reportValidity();
}
});
坑点:setCustomValidity() 一旦传入非空字符串,validity.customError 变为 true,该字段会永久校验失败,所以每次校验前必须先用空串清空。
validity 对象常用字段共 10 个:valueMissing、patternMismatch、typeMismatch、tooShort、tooLong、rangeUnderflow、rangeOverflow、stepMismatch、badInput、customError,全部为 false 时 valid 为 true。
红框样式怎么写才不误伤?
结论:不要直接写 :invalid,页面一加载空表单就全红;用 :user-invalid,或者提交后再加类名。
:user-invalid 支持情况:Chrome/Edge 119(2023 年 11 月)、Firefox 88、Safari 16.5。要兼容更老浏览器,就在首次提交后给 form 挂类名:
.was-validated input:invalid { border-color: #d93025; }
想绕过原生校验怎么办?
结论:form 上加 novalidate,或提交按钮上加 formnovalidate,浏览器就不执行任何约束验证,完全交给 JS。
两者区别是作用范围:novalidate 作用于整个表单的所有提交动作,formnovalidate 只作用于带该属性的那个提交按钮,适合做「保存草稿」这类跳过校验的按钮。
一句话收尾:required 挡空值、pattern 挡格式,pattern 必须和 required 同时出现才严丝合缝;再记住 pattern 无 flags、隐式整体匹配、非法转会失效这三点,原生表单校验就能覆盖绝大多数场景,剩下的自定义逻辑交给 setCustomValidity() 和 checkValidity()。
原文链接:https://www.gj0.com/thread-1210.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。