原生html表单校验需正确理解属性边界与行为:required仅在submit时触发提示;pattern仅对特定type生效且需锚点;setcustomvalidity('')不重置状态,须配合checkvalidity();空值判定依赖trim(),零宽字符等需额外处理。

原生 HTML 表单校验本身已是零依赖方案,所谓“打造校验器”,本质是避免踩坑、补足缺失行为、让 required、pattern、type="email" 等属性真正可靠可用——而不是写一堆 JS 封装一层假抽象。
为什么加了 required 却不报错?
浏览器只在表单提交(submit 事件)时触发 UI 提示,不是实时的。用户填完所有字段再点提交,才第一次看到红框和气泡。这不算“失效”,只是行为不符合直觉。
- 想离开字段就反馈?必须手动监听
blur或input,然后调用reportValidity() -
checkValidity()只返回true/false,不弹提示,别指望它“显示错误” - Safari 15.4 之前,
reportValidity()对setCustomValidity()设置的错误文本不渲染,旧版会静默失败 - 如果字段被
display: none或visibility: hidden,即使校验失败,reportValidity()也不会显示气泡
pattern 总是校验失败或放行非法值?
pattern 不是万能正则引擎:它只对 type="text"、"email"、"tel"、"password" 生效;对 type="number" 或 "date" 完全无效。且默认是“子串匹配”,不是全字符串匹配。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
- 写
pattern="[0-9]{11}"会允许"abc12345678901def"通过——必须加锚点:pattern="^1[3-9][0-9]{9}$" - 空值不归
pattern管,得配required才完整 - 避免用
\d,部分安卓 WebView 解析异常;改用[0-9]或[\d](注意双反斜杠转义) - 中文匹配写
[u4e00-u9fa5](小写十六进制,无反斜杠),别写u4E00-u9FA5或带\u
setCustomValidity('') 清不掉错误?
这是最隐蔽的坑:setCustomValidity('') 并非“重置校验状态”,而是设了一个空字符串错误——浏览器仍认为该字段处于“自定义校验中”,后续 checkValidity() 可能持续返回 false,哪怕输入已合法。
- 正确做法:只在非法时调用
setCustomValidity('错误信息');合法时统一调用setCustomValidity(''),且确保每次设置都覆盖前值 - 更稳妥的做法:合法时调用
setCustomValidity('')后,立刻触发一次input.checkValidity(),强制刷新内部状态 - 别依赖
title属性做提示——它不可靠,且无障碍支持差;统一用setCustomValidity()控制文案
隐藏字段、空格、JS 赋值导致校验失灵?
原生校验对“空”的判定极其朴素:input.value.trim() === ''。但很多真实场景下,值看起来不为空,实则含空格、Tab、零宽字符(\u200B)等。
- 用户粘贴进带 BOM 或零宽字符的内容,
.trim()清不掉,required仍报错 -
<select></select>首项写成<option value="">请选择</option>,value 为空就直接触发required拒绝 - 用 JS 直接赋值如
input.value = ' ',不会触发校验,DOM 状态也不变:invalid - 开发时别猜,直接在控制台执行
document.querySelector('input').value看原始值
真正的零依赖校验,不是堆属性,而是理解每个属性的生效边界、触发时机和兼容性缺口。一旦漏掉 reportValidity() 的显式调用,或误用 setCustomValidity(''),整个链路就断在看不见的地方。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










