You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用正则表达式实现JavaScript表单验证时的异常行为问题求助

问题根源与解决方案

首先,你的核心问题出在**setCustomValidity()的使用时机和浏览器原生表单验证的执行顺序**上:

当你首次输入无效内容时,调用input_name.setCustomValidity(err_msg)给输入框标记了错误状态。浏览器的原生表单验证机制会在你的submit事件监听器之前触发——如果输入框还处于无效状态(自定义错误未清除),浏览器会直接弹出错误提示,并且阻止submit事件的执行,这就是为什么后续修正输入后,你的console.log没有输出,因为事件根本没触发。

另外,你的handleSuccess里调用form.submit()是原生提交方法,它不会触发submit事件,所以提交成功时i也不会增加,不过这是次要问题。

修复步骤

1. 每次验证前先清除自定义错误

在开始验证之前,先调用input_name.setCustomValidity('')重置输入框的有效性状态,确保每次验证都是从零开始:

form.addEventListener("submit", function(e){
    i++
    console.log(`You tried to submit this form ${i} times`)
    e.preventDefault()
    let input_name = document.querySelector("#name")
    // 先重置自定义错误
    input_name.setCustomValidity('')
    let value = input_name.value.trim() // 先去除首尾空格,避免空字符干扰
    let regex = /^\w{2,}(\s+\w{2,})*$/
    
    if(regex.test(value)){
        handleSuccess.call(input_name)
    } else {
        let err_msg = `You must enter 1 or 2 words with at least 2 characters each`
        input_name.setCustomValidity(err_msg)
        handleError.call(form, new Error(err_msg))
    }
})

2. 简化名字处理逻辑

你之前的words和words_joined完全没必要,直接用trim()后的字符串匹配正则就行,正则本身已经支持1或多个符合要求的单词了。

3. 可选:添加input/blur事件实时清除错误

如果想让用户输入过程中错误提示自动消失,可以给输入框加个input事件监听器,实时重置自定义错误:

let input_name = document.querySelector("#name")
input_name.addEventListener('input', function(){
    this.setCustomValidity('')
})

4. 修正handleSuccess里的提交逻辑

如果希望提交成功时也能统计次数,不要用原生form.submit(),而是可以移除e.preventDefault()当验证通过时,或者手动触发事件(不过更简单的是验证通过后再决定是否阻止默认行为):

修改后的submit监听器可以调整为:

form.addEventListener("submit", function(e){
    i++
    console.log(`You tried to submit this form ${i} times`)
    let input_name = document.querySelector("#name")
    input_name.setCustomValidity('')
    let value = input_name.value.trim()
    let regex = /^\w{2,}(\s+\w{2,})*$/
    
    if(!regex.test(value)){
        e.preventDefault() // 只有验证失败才阻止默认提交
        let err_msg = `You must enter 1 or 2 words with at least 2 characters each`
        input_name.setCustomValidity(err_msg)
        handleError.call(form, new Error(err_msg))
    } else {
        handleSuccess.call(input_name)
        // 这里不需要手动submit,因为没有阻止默认行为
    }
})

这样调整后,无论首次输入是否有效,后续修正后都能正常触发submit事件,自定义错误提示也会正确显示/消失。

内容的提问来源于stack exchange,提问作者Sebastian Charras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 22:37:29