使用setTimeout和clearTimeout解决信用卡校验消息仅触发一次的问题
信用卡校验器交互优化问题
我正在开发一个信用卡校验器项目,校验功能validateCred已经正常工作,现在想优化交互逻辑:
- 用户输入卡号后按回车键,若无效则显示红色提示“This number is not valid.”,有效则显示绿色提示“This number is valid.”
- 提示消息需通过
setTimeout在2秒后自动消失
但目前的问题是:有效、无效状态的提示各只能触发一次,之后再输入就没反应了。我知道这和timeoutId及clearTimeout有关,但理不清具体逻辑,附上相关代码求助。
现有代码
HTML
<div class="credit-card"> <p class="credit-card__text">Want to check you if your credit card is valid?</p> <input type="number" id="userInput" class="js-input" placeholder="type in your number and press ENTER" onkeydown="handleEnter(event)"> <div> <p id="js-return-valid"></p> <p id="js-return-invalid"></p> </div> </div>
JavaScript
const displayValid = document.getElementById('js-return-valid'); const displayInvalid = document.getElementById('js-return-invalid'); let input = ''; function handleEnter(event) { if (event.key === 'Enter') { input = document.getElementById("userInput").value; input = String(input).split('').map((input) => { return Number(input) }); validateCred(input); if (!validateCred(input)) { setTimeout(function() { displayInvalid.style.display = "none"; }, 2000); displayInvalid.innerHTML = `This number is not valid.`; } else { setTimeout(function() { displayValid.style.display = "none"; }, 2000); displayValid.innerHTML = `This number is valid.`; } document.getElementById("userInput").value = null; } }
问题原因
- 第一次触发提示后,定时器会把元素设为
display: none,但后续触发时没有重置元素的display属性,导致内容更新后元素还是隐藏状态,看不到提示 - 没有清除之前的定时器,若短时间内连续触发不同状态,旧定时器会干扰新提示的显示时长
修复方案
优化后的JavaScript代码
const displayValid = document.getElementById('js-return-valid'); const displayInvalid = document.getElementById('js-return-invalid'); // 存储两个状态的定时器ID,用于后续清除 let validTimeoutId = null; let invalidTimeoutId = null; function handleEnter(event) { if (event.key === 'Enter') { const inputValue = document.getElementById("userInput").value; const input = String(inputValue).split('').map(num => Number(num)); // 只调用一次校验函数,避免重复计算 const isValid = validateCred(input); // 清除所有待执行的定时器,防止状态冲突 clearTimeout(validTimeoutId); clearTimeout(invalidTimeoutId); if (!isValid) { // 显示无效提示,同时隐藏有效提示 displayInvalid.style.display = "block"; displayInvalid.textContent = "This number is not valid."; displayValid.style.display = "none"; // 设置新的定时器,2秒后隐藏无效提示 invalidTimeoutId = setTimeout(() => { displayInvalid.style.display = "none"; }, 2000); } else { // 显示有效提示,同时隐藏无效提示 displayValid.style.display = "block"; displayValid.textContent = "This number is valid."; displayInvalid.style.display = "none"; // 设置新的定时器,2秒后隐藏有效提示 validTimeoutId = setTimeout(() => { displayValid.style.display = "none"; }, 2000); } document.getElementById("userInput").value = ""; } }
可选CSS优化
提前给提示元素设置样式和初始隐藏状态,让代码更简洁:
#js-return-valid { color: green; display: none; margin: 10px 0; } #js-return-invalid { color: red; display: none; margin: 10px 0; }
内容的提问来源于stack exchange,提问作者Veelcheck
相关产品推荐
相关产品推荐

