自定义表单校验规则不生效怎么办?

UI正宇 阅读 18

我在用原生 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>

到底哪里出问题了?是不是事件没触发还是返回值没处理?

我来解答 赞 7 收藏
二维码
手机扫码查看
2 条解答
Mr-艳玲
Mr-艳玲 Lv1
你的问题出在正则表达式转义字符上,d应该写成d。另外表单提交时没处理验证返回值,我帮你优化下:

function validatePhone() {
const phone = document.getElementById('phone').value;
const reg = /^1[3-9]d{9}$/; // 这里修正了转义
const errorEl = document.getElementById('phone-error');

if (!reg.test(phone)) {
errorEl.innerText = '手机号格式不正确';
return false;
}
errorEl.innerText = ''; // 清空正确时的错误提示
return true;
}

// 表单提交时这样处理
document.querySelector('form').addEventListener('submit', function(e) {
if (!validatePhone()) {
e.preventDefault(); // 阻止提交
}
});


顺手还做了两处优化:
1. 缓存了error元素避免重复查询
2. 验证通过时清空错误提示

你的HTML写法没问题,但建议把事件绑定移到JS里更干净。如果还不行,可能是表单没正确获取,检查下选择器。
点赞
2026-03-07 21:27
UP主~永穗
我刚看了一下你的代码,问题出在几个地方,我来一条条帮你理清楚。

首先,正则表达式里有个小错误,你写的是 /^1[3-9]d{9}$/,这里的 d 是小写的,应该是 d 才对,也就是反斜杠加 d,表示数字字符。不然这个正则其实匹配的是字母 d,不是数字,所以你输啥都不报错,因为它永远匹配不上。

改完之后应该是:
/^1[3-9]d{9}$/

这个错误会导致整个校验逻辑完全失效,因为正则没写对,reg.test(phone) 总是返回 false,但你可能没注意到错误信息没出来是因为你没看到变化,或者误以为“没反应”是没触发。

其次,这里有个关键点要注意:你只在 onblur 里调用了 validatePhone(),但没有在表单提交时做最终拦截。用户可能直接点提交按钮,根本没触发 onblur,所以表单就提交出去了。这在实际开发中很常见——校验只在失焦时做,但用户可能直接回车提交,或者跳过输入直接点按钮。

所以建议你再加一个统一的校验函数,比如叫 validateForm(),在 onsubmit 里调用它,把所有字段的校验都包进去,最后统一决定是否允许提交。

举个完整例子,我帮你改一下:

HTML 部分:
<form id="register-form">
<input type="text" id="phone" placeholder="请输入手机号">
<span id="phone-error" style="color: red;"></span>
<button type="submit">注册</button>
</form>


JS 部分:
// 先封装一个校验手机号的函数,记得修正常见错误
function validatePhone() {
const phone = document.getElementById('phone').value.trim(); // 加个 trim 比较稳妥,去掉首尾空格
const reg = /^1[3-9]d{9}$/; // 注意这里是 d,不是 d
if (!reg.test(phone)) {
document.getElementById('phone-error').innerText = '手机号格式不正确';
return false;
}
// 校验通过,清空错误信息(养成好习惯)
document.getElementById('phone-error').innerText = '';
return true;
}

// 再写一个总校验函数,提交时调用
function validateForm() {
const isPhoneValid = validatePhone();
return isPhoneValid; // 这里你可以加更多字段,比如密码、邮箱等,用 && 连起来
}

// 绑定 onblur 事件,失焦时即时反馈
document.getElementById('phone').addEventListener('blur', function() {
validatePhone();
});

// 绑定表单提交事件,阻止非法提交
document.getElementById('register-form').addEventListener('submit', function(e) {
const isValid = validateForm();
if (!isValid) {
e.preventDefault(); // 阻止表单提交
}
});


这里有个容易忽略的点:你原来的 HTML 是内联事件 onblur="validatePhone()",这种方式虽然能用,但不推荐,特别是当你的逻辑稍微复杂点,或者你以后要加多个校验时,内联事件会让代码很难维护。用 addEventListener 更灵活,也更符合现代 JS 写法。

还有一个细节:你写的错误提示 span 是空的,但没设置宽度,有时候文字没显示出来可能是被压缩了,建议加个 display: block 或者 min-height: 1em 确保它占位。

最后说个实际开发中踩过的坑:如果你用的是 input type="tel",有些浏览器会自动做基础校验(比如只允许数字),但原生 HTML5 校验不会自动触发你的 JS 逻辑,所以还是得自己写。

我建议你先按上面把正则修好,再加个提交拦截,基本就能解决“没反应”的问题了。如果还有问题,可以把你完整的 HTML 和 JS 贴出来,我帮你再看看是不是其他地方有冲突。
点赞 4
2026-02-25 11:01