表单校验时如何同时验证手机号和验证码?
我做登录页,需要用户填手机号和短信验证码。现在用的是 HTML5 的 <input type="tel"> 加 pattern 校验手机号,但验证码是 6 位数字,不知道怎么把两个字段联动起来一起校验。
比如用户改了手机号,之前的验证码就失效了,这时候应该清空验证码输入框并提示。但我试了在手机号的 onchange 里清空验证码,结果表单整体校验还是通过了,因为验证码字段本身格式是对的。这逻辑该怎么处理才对?
const phoneInput = document.getElementById('phone');
const codeInput = document.getElementById('code');
phoneInput.addEventListener('change', () => {
codeInput.value = '';
// 但此时如果直接点提交,codeInput 因为空值会触发 required 提示,
// 可如果用户手动输了个 6 位数,哪怕手机号变了,校验也会过……
});
思路是这样的:
当手机号变化时,你清空了验证码输入框的值,但表单校验不会自动知道这两个字段有关联。你需要手动给验证码字段设置一个"校验失败"的状态,直到用户重新获取并填写验证码。
用 HTML5 的 Constraint Validation API 可以做到,核心方法是
setCustomValidity。完整实现:
原理解释:
setCustomValidity('')是关键。默认情况下,元素的 customValidity 是空字符串,表示校验通过。当你设置一个非空字符串时,浏览器会认为这个字段校验失败,即使格式完全正确也不会通过。所以流程是:
1. 用户修改手机号 → 触发 change 事件 → 清空验证码 + 设置 customValidity 为"请重新获取验证码"
2. 此时验证码字段状态是"有错误",即使用户手动输入 6 位数字,
checkValidity()也会返回 false3. 用户重新输入验证码 → 触发 input 事件 → 检测到是 6 位数字 → 清除 customValidity,校验恢复正常
补充一点:
如果你还需要在服务端校验验证码是否匹配(这是必须的,前端校验不够安全),可以在提交时把手机号和验证码一起发给后端验证。前端的校验主要是提升用户体验,真正保证安全还是得靠后端。