表单约束验证 required pattern

chinaz
chinaz 初级会员超兽战士
发布于 2026-10-08 21:52 ·1 浏览 ·0 回复

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()。

版权声明:本文来自 GJ站长论坛《表单约束验证 required pattern》
原文链接:https://www.gj0.com/thread-1210.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。

全部回复 0

还没有回复,来抢沙发~