自定义表单校验规则不生效怎么办?
我在用原生 JavaScript 做一个注册表单,想对手机号做自定义校验,但写了验证函数后发现不管输什么都没反应,错误提示也不显示。我试过在 onblur 事件里调用校验函数,也绑定了 onsubmit 阻止默认提交,但就是没效果。
这是我的校验逻辑:
function validatePhone() {
const phone = document.getElementById('phone').value;
const reg = /^1[3-9]d{9}$/;
if (!reg.test(phone)) {
document.getElementById('phone-error').innerText = '手机号格式不正确';
return false;
}
return true;
}
HTML 里是这样写的:
<input type="text" id="phone" onblur="validatePhone()">
<span id="phone-error" style="color: red;"></span>
到底哪里出问题了?是不是事件没触发还是返回值没处理?
d应该写成d。另外表单提交时没处理验证返回值,我帮你优化下:顺手还做了两处优化:
1. 缓存了error元素避免重复查询
2. 验证通过时清空错误提示
你的HTML写法没问题,但建议把事件绑定移到JS里更干净。如果还不行,可能是表单没正确获取,检查下选择器。
首先,正则表达式里有个小错误,你写的是
/^1[3-9]d{9}$/,这里的d是小写的,应该是d才对,也就是反斜杠加 d,表示数字字符。不然这个正则其实匹配的是字母 d,不是数字,所以你输啥都不报错,因为它永远匹配不上。改完之后应该是:
/^1[3-9]d{9}$/这个错误会导致整个校验逻辑完全失效,因为正则没写对,
reg.test(phone)总是返回 false,但你可能没注意到错误信息没出来是因为你没看到变化,或者误以为“没反应”是没触发。其次,这里有个关键点要注意:你只在
onblur里调用了validatePhone(),但没有在表单提交时做最终拦截。用户可能直接点提交按钮,根本没触发onblur,所以表单就提交出去了。这在实际开发中很常见——校验只在失焦时做,但用户可能直接回车提交,或者跳过输入直接点按钮。所以建议你再加一个统一的校验函数,比如叫
validateForm(),在onsubmit里调用它,把所有字段的校验都包进去,最后统一决定是否允许提交。举个完整例子,我帮你改一下:
HTML 部分:
JS 部分:
这里有个容易忽略的点:你原来的 HTML 是内联事件
onblur="validatePhone()",这种方式虽然能用,但不推荐,特别是当你的逻辑稍微复杂点,或者你以后要加多个校验时,内联事件会让代码很难维护。用addEventListener更灵活,也更符合现代 JS 写法。还有一个细节:你写的错误提示
span是空的,但没设置宽度,有时候文字没显示出来可能是被压缩了,建议加个display: block或者min-height: 1em确保它占位。最后说个实际开发中踩过的坑:如果你用的是
input type="tel",有些浏览器会自动做基础校验(比如只允许数字),但原生 HTML5 校验不会自动触发你的 JS 逻辑,所以还是得自己写。我建议你先按上面把正则修好,再加个提交拦截,基本就能解决“没反应”的问题了。如果还有问题,可以把你完整的 HTML 和 JS 贴出来,我帮你再看看是不是其他地方有冲突。