直接禁用表单原生验证用novalidate属性;绕过单个按钮验证用formnovalidate;iOS提交失败多因非用户直接触发,应优先用requestSubmit();IE10/11验证不显示反馈但逻辑仍生效,需手动调setCustomValidity('')重置。

直接禁用整个表单的原生验证:用 novalidate
想彻底关掉浏览器自带的「必填提示」「邮箱格式气泡」?在 标签上加 novalidate 就行,不用 JS,一行搞定:
它会跳过所有字段的 required、type="email"、pattern 等校验,连 :valid/:invalid 伪类都还会计算(只是不弹窗、不拦提交),所以 CSS 样式可能仍生效——这点常被忽略。
只绕过某个按钮的验证:用 formnovalidate
常见场景:「保存草稿」不该校验,但「提交订单」必须校验。这时别动 用户点了按钮,但表单没发出去?大概率是 iOS Safari 静默拦截了「非用户直接触发」的提交。比如: IE 下点提交,没气泡、不拦住、看着像失效?错觉。它的 立即学习“前端免费学习笔记(深入)”; 真正麻烦的不是写几行 JS,而是每个验证字段都得手动 reset + validate + focus,否则表单就僵在错误态里出不来。,只给对应按钮加属性:
注意:formnovalidate 只对 type="submit" 按钮有效;如果用 或 iOS 表单提交失败:不是验证问题,是触发方式被拦截
• 在 setTimeout 或 Promise.then 里调 form.submit()
• 绑定的是 touchend 而非 click
• 在 input 的 blur 事件里自动提交
✅ 正确做法:
• 用 addEventListener('click', handler) 绑定
• 提交时优先用 form.requestSubmit()(iOS 16.4+ 支持,带校验且能被监听)
• fallback 时才用 form.submit()(它不派发 submit 事件,也不走验证)IE10/11 验证“失效”:其实是没反馈,不是没校验
checkValidity() 仍返回布尔值,只是 UI 层压根不显示。更坑的是:一旦某个字段触发过 invalid 事件,后续即使输对了,checkValidity() 还是返回 false,除非你手动调 input.setCustomValidity('') 清空状态。
关键操作:
• 所有带验证的 必须监听 input 或 blur
• 在事件里先调 input.setCustomValidity('')
• 仅当真不合法时,再设错误信息,如 input.setCustomValidity('邮箱格式不对')
• 别信 :valid 伪类——IE 动态更新极差,全靠 JS 读 input.validity.valid











