pattern 在提交或调用 checkValidity() 时生效,非实时校验;空字符串默认通过(除非加 required);正则需全匹配,浏览器自动隐式添加 ^ 和 $。

pattern 属性不能实时校验,只在提交或调用 checkValidity() 时触发;空字符串默认通过(除非加 required);正则必须全匹配,但不用手动写 ^ 和 $ —— 浏览器内部已隐式包裹。
pattern 什么时候生效?
很多人把 pattern 当成 JS 的 input 事件监听器,结果输错内容毫无反馈。它只在两个时机起作用:用户点击 type="submit" 按钮,或脚本主动调用 form.checkValidity() / form.reportValidity()。不触发 input、blur 或粘贴事件的即时校验。
这意味着:
- 若要输入过程中标红或禁用提交按钮,必须配合
input事件 +setCustomValidity() - 单独写
pattern却没加required,空值会直接通过校验 - 移动端 Safari 不显示
title提示,iOS 用户可能完全看不到错误文案
手机号 pattern 正则怎么写才不踩坑?
用 pattern="1[3-9]d{9}" 是最常用写法,但它只覆盖传统号段,漏掉 14(部分已开放)、170/171、166、198/199 等。想“更全”反而容易出问题:
- 别用
^1([3-9]d|4[0-9]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-9])d{8}$这类长正则——pattern对 Unicode 和复杂语法支持弱,Chrome 可能认,旧版 Firefox 直接失效 - 不要在 pattern 中写
s、D或g/i标志,浏览器不识别 - 点号
.要写成.,而 HTML 属性里得双写反斜杠 →\. - 推荐务实做法:
pattern="1[3-9]d{9}"+ 后端二次校验,比前端硬塞所有号段更可靠
为什么一定要配 inputmode="tel" 和 type="tel"?
type="tel" 本身不校验格式,只优化键盘;pattern 负责校验逻辑。两者分工明确:
- 只设
type="tel":Android/iOS 弹出数字键盘,但用户仍可粘贴字母,pattern才拦住非法内容 - 只设
pattern+type="text":PC 端没问题,但 Android Chrome 某些版本下,type="tel"反而会绕过pattern校验 - 稳妥组合:
type="text" inputmode="tel"(Android 更稳)+pattern="1[3-9]d{9}"+required - iOS Safari 16.4 以下不支持
inputmode,可 fallback 用type="tel",但别同时设type="tel"和 JS 的keypress拦截——容易卡顿
title 提示和 CSS 状态反馈怎么配合?
title 是唯一能影响原生提示文案的属性,但它不是 placeholder,也不控制样式:
-
title内容只在提交失败时作为 tooltip 显示,且 Safari 移动端基本不渲染 - 视觉反馈靠 CSS 伪类:
input:invalid:not(:placeholder-shown)控制红色边框,input:valid控制绿色边框 - 注意:
:invalid在空值时也触发(除非加required),所以要用:not(:placeholder-shown)排除占位符状态下的误判 - 别依赖
oninvalid事件做自定义提示——它不冒泡,且触发时机难控,不如统一用submit事件捕获并集中处理
真正容易被忽略的是:pattern 的正则引擎和 JS 的 RegExp.test() 行为不一致。你在控制台跑通了 /^1[3-9]d{9}$/.test("13812345678"),不等于放进 pattern 就一定生效。务必真机测试提交流程,而不是只信 console 输出。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











