formnovalidate 是仅对 type="submit" 有效的布尔属性,用于使点击该按钮时跳过表单验证;它不适用于 type="button" 或 type="reset",且优先级高于 form 的 novalidate 属性。

formnovalidate 是什么,它只对 type="submit" 有效
formnovalidate 是一个布尔属性,作用是让某个提交按钮绕过表单的内置验证(比如 required、type="email" 等触发的检查)。但它**不会**对 type="button" 或 type="reset" 生效——只有 type="submit" 按钮加上 formnovalidate 才能跳过验证。
常见错误是给普通按钮加这个属性,结果发现完全没反应。这是因为浏览器只在触发表单提交(即 submit 事件)时才检查验证逻辑,而 formnovalidate 只是告诉浏览器:“这次 submit 别校验”。
-
<button type="submit" formnovalidate>取消</button>✅ 有效 -
<button type="button" formnovalidate>取消</button>❌ 属性被忽略 -
<input type="submit" formnovalidate value="保存草稿">✅ 有效
多个 submit 按钮共存时,怎么控制各自是否验证
一个 <form> 可以有多个 type="submit" 按钮,每个都可以独立决定是否跳过验证。关键在于:哪个按钮被点击,就执行哪个按钮上声明的验证策略。
例如“保存”要校验,“暂存”不校验,直接在对应按钮上加 formnovalidate 即可:
立即学习“前端免费学习笔记(深入)”;
<form> <input name="email" required type="email"> <button type="submit">保存(需校验)</button> <button type="submit" formnovalidate>暂存(不校验)</button> </form>
注意:不要试图用 JavaScript 删除 required 或临时改 novalidate 在 <form> 上——那样会影响所有按钮,且容易漏恢复、引发竞态。
- 验证行为由点击的按钮决定,不是由表单整体决定
-
formnovalidate和formaction、formmethod一样,属于“按钮级覆盖” - 如果用了
form属性把按钮指向外部表单,formnovalidate依然生效,但目标表单必须存在
formnovalidate 和 novalidate 的区别与误用风险
novalidate 是写在 <form> 标签上的,它会让整个表单所有提交都跳过验证;而 formnovalidate 是按钮级开关,更细粒度、更安全。
容易踩的坑是:为了“某个按钮不验证”,干脆给整个 <form novalidate>,结果导致其他按钮也失去校验,后续还得手动用 JS 补验证逻辑——反而增加复杂度和出错概率。
-
<form novalidate>→ 全局关闭,所有 submit 都不校验 -
<button formnovalidate>→ 仅该按钮提交时不校验,其余照常 - 两者同时存在时,
formnovalidate优先级更高(但没必要混用)
兼容性与移动端注意事项
formnovalidate 在所有现代浏览器(Chrome、Firefox、Safari、Edge)中都支持,包括 iOS Safari 12.2+ 和 Android Chrome 57+。IE10+ 也支持,但 IE9 及更早版本不支持——如果还要兼容 IE9,只能靠 JS 拦截 submit 事件并调用 event.preventDefault() 后手动提交。
移动端特别要注意:某些 WebView(如早期微信内置浏览器)可能对 formnovalidate 解析不稳定,建议加简单测试,比如点击“暂存”按钮后检查是否真的没弹出“请填写此字段”提示。
- 不要依赖 CSS 类或 data 属性模拟行为,原生属性最可靠
- 如果按钮是动态插入的,确保插入 HTML 时就带上
formnovalidate,而不是 later 用 JS setAttribute —— 某些旧 WebView 对 JS 动态添加该属性响应不及时



















