使用正则表达式实现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

