HTML 表单约束验证怎么用:required 和 pattern 入门指南

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

结论: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 位手机号">

三条硬规则:

  1. pattern="\d{6}" 表示整个值恰好 6 位数字。写 \d{6} 时 1234567 不通过,因为要求整串匹配。
  2. 不能写 pattern="/\d{6}/i"。要忽略大小写就写字符类 [a-zA-Z],没有 i 标志可加。
  3. 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 避免一进页面就飘红。

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

全部回复 0

还没有回复,来抢沙发~