JavaScript中如何在邮箱一致性校验不通过时阻止表单提交
问题根源
当前代码存在3个核心疏漏,导致表单无法拦截不匹配的提交行为:
- 校验逻辑仅绑定在二次输入邮箱的失焦变更事件上,完全没有接入表单提交流程,浏览器不会感知自定义的校验结果,默认执行原生提交动作
- 校验函数没有输出明确的校验状态,即使识别出邮箱不匹配,也没有任何逻辑主动阻止浏览器提交
- 代码执行流程存在漏洞:一旦触发不匹配的
throw逻辑,后续用于清除错误样式、隐藏提示的代码会被直接中断,永远不会执行
具体实现方法
第一步:调整校验函数,增加状态返回
修改原有的validateEmail函数,让它能明确返回校验通过/不通过的状态,同时修正原有代码的流程漏洞:
"use strict"; // global variables var profile = {}; // 全局缓存邮箱校验状态 var isEmailMatch = false; function validateEmail() { var email1Input = document.getElementById("email"); var email2Input = document.getElementById("email_retype"); email1Input.value = email1Input.value.toLowerCase(); email2Input.value = email2Input.value.toLowerCase(); var errorDiv = document.getElementById("emailError"); // 样式和提示逻辑前置,避免throw中断后续代码执行 email1Input.style.background = ""; email2Input.style.background = ""; errorDiv.style.display = "none"; errorDiv.innerHTML = ""; try { if (email1Input.value.localeCompare(email2Input.value) !== 0) { throw "The e-mails do not match"; } // 校验通过,更新状态 isEmailMatch = true; return isEmailMatch; } catch(msg) { // 展示错误提示 errorDiv.style.display = "block"; errorDiv.innerHTML = msg; // 标记错误输入样式 email1Input.style.background = "rgb(255,233,233)"; email2Input.style.background = "rgb(255,233,233)"; // 校验不通过,更新状态 isEmailMatch = false; return isEmailMatch; } }
第二步:给表单绑定提交拦截逻辑
在原有的createEventListeners函数里,获取页面的表单元素,绑定提交事件,当校验不通过时阻止默认提交行为:
function createEventListeners() { var email2Input = document.getElementById("email_retype"); if (email2Input.addEventListener) { email2Input.addEventListener("change", validateEmail, false); } else if (email2Input.attachEvent) { email2Input.attachEvent("onchange", validateEmail); } // 新增:获取表单元素,绑定提交拦截逻辑 var form = document.querySelector("form"); if (form.addEventListener) { form.addEventListener("submit", function(e) { // 提交前重新执行一次校验,覆盖用户跳过失焦校验直接点提交的场景 validateEmail(); // 校验不通过时,拦截默认提交动作 if (!isEmailMatch) { e.preventDefault(); } }, false); } else if (form.attachEvent) { form.attachEvent("onsubmit", function() { validateEmail(); // 兼容旧IE的表单提交拦截逻辑 return isEmailMatch; }); } // 保留原有lodgings元素的绑定逻辑 var lodgings = document.getElementsByName("lodgings"); if (lodgings[0].addEventListener) { for (var i = 0; i < lodgings.length; i++) { lodgings[i].addEventListener("change", registerLodging, false); } } else if (lodgings[0].attachEvent) { for (var i = 0; i < lodgings.length; i++) { lodgings[i].attachEvent("onchange", registerLodging); } } } // 保留原有window加载绑定逻辑 if (window.addEventListener) { window.addEventListener("load", createEventListeners, false); } else if (window.attachEvent) { window.attachEvent("onload", createEventListeners); }
额外优化建议
- 可以把校验逻辑同时绑定在第一个邮箱输入框的
input事件上,用户修改任意一个邮箱内容时都能实时更新匹配状态 - 提交环节的重校验逻辑是必要的,可避免用户输完内容没有触发失焦事件、直接点击提交按钮导致校验失效的问题
内容的提问来源于stack exchange,提问作者Brian N
相关产品推荐
相关产品推荐

