required仅对text、email、number、tel、url、date、checkbox、radio、file、select、textarea等具空值语义的控件生效;校验仅触发于type="submit"点击或可编辑字段回车,且表单须在dom中连接、未disabled、未preventdefault而未调checkvalidity。

直接加 required 属性就行,但加了不生效、提示不出现、移动端失效——这些问题几乎都出在类型、触发方式或 DOM 状态上,不是属性本身写错了。
哪些表单元素加 required 才真起作用
它只对有明确“空值语义”的控件生效,不是所有 input 都能用:
-
input[type="text"]、input[type="email"]、input[type="number"]、input[type="tel"]、input[type="url"]、input[type="date"]—— 空字符串""就算“没填” -
input[type="checkbox"]—— 必须勾选,否则校验失败 -
input[type="radio"]—— 同name组里任意一个带required,就表示该组至少选一个 -
select—— 必须含一个<option value=""></option>,且不能加selected,否则用户不点也能绕过 -
textarea—— 支持,空格字符串" "会被视为已填(required不自动 trim) -
input[type="file"]—— 至少选一个文件才通过;但旧版 iOS Safari(≤15.4)支持不稳定,建议 JS 降级兜底 -
input[type="hidden"]、input[type="button"]、input[type="range"]、input[type="color"]—— 加了也无效,浏览器直接忽略
为什么点了提交没反应、也没提示
原生校验只响应两种动作:点击 type="submit" 按钮,或在可编辑字段中按回车。其他情况一律跳过:
- 按钮写成
<button type="button"></button>或没写type(默认是button),不是submit - 表单没包在
<form></form>标签里,或form被 JS 动态移除/替换 - JS 中调用了
event.preventDefault(),但没手动执行form.checkValidity() - 用
form.submit()直接提交 —— 这个调用完全绕过所有原生校验逻辑 - 字段被设为
disabled(跳过校验),或readonly(仍参与校验) - CSS 隐藏了浏览器原生提示,比如写了
input::-webkit-validation-bubble { display: none; }
如何让 required 和 JS 协同工作更可靠
原生 required 是第一道防线,但业务逻辑常需要动态控制或补充反馈:
- 条件必填(例如选“其他”才要求填备注):用 JS 切换
el.required = shouldRequire,别只靠 HTML 写死 - 提交前主动检查:监听
submit事件,调form.checkValidity(),返回false时聚焦首个:invalid字段 - 避免首次渲染即报错:React/Vue 等框架中,受控组件初始化
value应为"",而非undefined或null - 自定义提示文案:用
el.setCustomValidity("请输入手机号"),清空时传空字符串el.setCustomValidity("") - 延迟显示红框反馈:用
input:invalid:not(:placeholder-shown)替代单纯:invalid,避免初始加载就标红
最常被忽略的一点:空格字符串 " "、全角空格、"000"、"null" 这些在前端可能被 required 放过,但后端必须统一判为空并拒绝——前后端对“空”的定义要一致,不能只信前端。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











