JavaScript表单验证合法输入仍报错 加preventDefault仍提交问题
问题原因
你的代码存在4个核心错误,导致校验逻辑完全不符合预期:
- 函数声明缺失:你贴出的JS代码缺少
function validate() {}的外层函数包裹,form标签上绑定的onsubmit="return validate()"找不到对应执行函数,校验逻辑根本不会运行,表单会直接默认提交。 - 取值逻辑完全错误:
getAttribute()只能读取HTML标签上预先写死的属性值,你既没有在input标签上定义length、pattern属性,也没有通过.value读取用户实时输入的内容,判断条件永远为真,所以不管输入什么内容都会弹出错误。 - 错误状态没有重置:你只在校验失败时给元素加错误样式,校验通过时从来没有移除过这些样式,只要触发过一次报错,后续哪怕输入合法,错误提示也会一直显示。
- 校验逻辑耦合:你把姓、名两个字段的校验写在同一个if判断里,只要任意一个字段不符合规则,两个字段的错误提示会同时弹出,无法精准提示错误位置。另外你直接用字符串和正则规则做相等比对,根本无法实现正则校验,正则校验需要调用
test()方法执行匹配。
修正方案
CSS部分不需要修改,只需要调整HTML和JS逻辑即可:
修正后的HTML
<form id="form" novalidate onsubmit="return validate()"> <label for="firstName">Enter your first name</label><br> <input type="text" id="firstName" name="firstName" required><br> <span role="alert" id="nameError" aria-hidden="true"> Please enter a valid name (at least 3 letters) </span> <label for="lastName">Enter your last name here</label><br> <input type="text" id="lastName" name="lastName" required><br> <span role="alert" id="lastNameError" aria-hidden="true"> Please enter a valid name (at least 3 letters) </span> <button type="submit">Submit</button> <!-- 其他表单元素 --> </form>
修正后的JavaScript
function validate() { const firstNameField = document.getElementById("firstName"); const lastNameField = document.getElementById("lastName"); const nameError = document.getElementById("nameError"); const lastNameError = document.getElementById("lastNameError"); // 匹配纯字母的正则规则 const nameReg = /^[A-Za-z]+$/; // 每次提交先重置所有错误状态 let valid = true; // 重置名字字段状态 nameError.classList.remove("visible"); firstNameField.classList.remove("invalid"); nameError.setAttribute('aria-hidden', true); firstNameField.removeAttribute('aria-invalid'); // 重置姓氏字段状态 lastNameError.classList.remove("visible"); lastNameField.classList.remove("invalid"); lastNameError.setAttribute('aria-hidden', true); lastNameField.removeAttribute('aria-invalid'); // 单独校验名字:去掉首尾空格后长度≥3,且全为字母 const firstNameVal = firstNameField.value.trim(); if (firstNameVal.length < 3 || !nameReg.test(firstNameVal)) { nameError.classList.add("visible"); firstNameField.classList.add("invalid"); nameError.setAttribute('aria-hidden', false); firstNameField.setAttribute('aria-invalid', true); valid = false; } // 单独校验姓氏 const lastNameVal = lastNameField.value.trim(); if (lastNameVal.length < 3 || !nameReg.test(lastNameVal)) { lastNameError.classList.add("visible"); lastNameField.classList.add("invalid"); lastNameError.setAttribute('aria-hidden', false); lastNameField.setAttribute('aria-invalid', true); valid = false; } // 校验通过返回true触发表单提交,否则返回false阻止提交 return valid; }
额外说明
- 读取用户输入的内容必须用
元素.value,要获取输入内容长度用元素.value.length,getAttribute无法拿到用户实时输入的内容。 - 正则校验必须通过
正则规则.test(待校验字符串)的方式执行,直接拿字符串和正则表达式做相等判断永远不会得到正确结果。 - 你不需要额外加
preventDefault(),onsubmit上绑定的函数返回false时会自动阻止表单提交,返回true时才会正常提交。
内容的提问来源于stack exchange,提问作者Munia11
相关产品推荐
相关产品推荐

