required属性生效需同时满足四个条件:form标签完整包裹、触发submit事件、元素类型支持、value为空字符串;否则表单静默提交。

required 属性本身不能独立生效,它只在特定组合下才真正起作用——漏掉任何一个前提,表单就静默提交成功。
required 属性生效的四个硬性条件
浏览器不会因为你在 input 上写了 required 就自动拦住空提交。必须同时满足:
-
<form></form>标签完整包裹所有带required的控件;缺一层外层form,整个校验链就断了 - 触发动作必须是原生
submit事件:按钮得是<button type="submit"></button>或<input type="submit">;type="button"或 JS 调用form.submit()都绕过校验 - 目标元素类型必须支持:
input(排除type="hidden"、"button"等)、select、textarea;自定义组件或div[contenteditable]加了也白加 - “空值”判定只看 DOM 的
value属性:" "(含空格)算已填,""(纯空字符串)才算空;select的首个<option value=""></option>若没加disabled,选中它照样报错
为什么加了 required 却没弹提示?常见静默失败场景
不是属性写错了,而是环境没搭对:
- 你在
submit事件监听里写了e.preventDefault(),却没紧接着调form.checkValidity()——这等于主动关掉了浏览器校验开关 - 用了
<button onclick="handleSubmit()"></button>,没设type="submit",浏览器压根不启动验证流程 -
select的默认项写成<option value="">请选择</option>,没加disabled selected,用户没动它,就一直卡在校验失败状态 - 移动端 WebView(比如旧版微信内置浏览器)直接忽略
required,连checkValidity()都返回true,必须额外降级检测
让红边/星号/提示文字“等用户动过再反馈”的技巧
:invalid 伪类一加载就生效,会导致页面刚打开所有必填框全变红。要让它“延迟反馈”,得组合使用:
- 给
input加placeholder,然后用input:invalid:not(:placeholder-shown)控制样式,避免初始误标 -
label后加星号不能只靠 CSS:label::after { content: " *"; color: #d32f2f; },还得同步写aria-required="true"保证读屏器可识别 - 想失焦即提示(而非等提交),必须监听
blur,手动调input.reportValidity()——它会触发原生气泡,且返回布尔值供你判断 - 别在
input事件里反复调setCustomValidity(),容易让浏览器内部validity状态混乱;清空错误必须显式调input.setCustomValidity("")
自定义提示文案的唯一可靠路径
浏览器默认提示(如“请填写此字段”)无法通过 HTML 或 CSS 修改。唯一能控制它的方法是:
- 监听
invalid事件,在回调中调用event.target.setCustomValidity("请输入真实姓名") - 注意:该设置是一次性的,每次校验前都需重置;若要恢复默认提示,得调
setCustomValidity("") - 不要依赖
title属性改提示——它只对pattern生效,对required无效
最易被忽略的一点:空格不算空,value.trim() === "" 和浏览器的 required 判定逻辑不一致;如果业务上认为“只输空格”也算未填,就必须用 JS 补充校验,不能指望原生行为覆盖全部语义。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











