多输入框长数字粘贴自动拆分功能异常及优化需求
问题根源分析
- 粘贴拆分逻辑错误:你使用的
split(/(?=(?:..)*$)/g)是从右向左每两位拆分字符串,比如45896会被拆成["4", "58", "96"],这就导致第一个输入框只得到1位数字,最后一个输入框反而有值,和你期望的左到右拆分、最后一个留空完全相反。 - 粘贴后未触发验证:
handleChange仅在输入框onchange时执行,但粘贴操作不会自动触发这个事件,所以补0和报错逻辑都没生效。 - 验证函数逻辑顺序问题:
handleChange里先补0再判断长度的顺序会导致后续的长度判断失效,而且范围判断的条件有冗余。
解决方案
1. 修复粘贴拆分逻辑
把从右往左的拆分改成从左往右每两位拆分,用match(/.{1,2}/g)可以实现。同时,拆分后如果数组长度不足输入框数量,后面的位置补空字符串,保证最后一个输入框在长度不够时留空。
2. 粘贴后触发验证
设置完所有输入框的值后,逐个调用handleChange,让补0和报错逻辑生效。
3. 调整验证函数逻辑
重新梳理handleChange的判断顺序,先处理空值和范围,再处理补0,确保逻辑通顺。
修改后的完整代码
<style> .circle input { border-radius: 999px; float: left; max-width: 100px; font-size: 2em; text-align: center; height: 100px; margin-right: 10px; } </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form id="tkt_1"> <div class="circle"> <input type="tel" min="1" max="99" minlength="2" maxlength="2" oninput="if((this.value.length) > 2) {this.value = this.value.substring(0, 2);}" onchange="handleChange(this);" placeholder="00" /> </div> <div class="circle"> <input type="tel" min="1" max="99" minlength="2" maxlength="2" oninput="if((this.value.length) > 2) {this.value = this.value.substring(0, 2);}" onchange="handleChange(this);" placeholder="00" /> </div> <div class="circle"> <input type="tel" min="1" max="99" minlength="2" maxlength="2" oninput="if((this.value.length) > 2) {this.value = this.value.substring(0, 2);}" onchange="handleChange(this);" placeholder="00" /> </div> </form> <script> // Paste numbers from clipboard in multiple input document.addEventListener("paste", function (e) { if (e.target.type === "tel") { e.preventDefault(); var data = e.clipboardData.getData('Text').replace(/[^0-9]/g, ""); // 从左往右每两位拆分,不足两位的保留最后一段 let splitData = data.match(/.{1,2}/g) || []; const inputs = document.querySelectorAll("input[type=tel]"); // 遍历输入框,赋值后触发验证 inputs.forEach((node, index) => { node.value = splitData[index] ?? ""; handleChange(node); }); } }); // Validation function handleChange(input) { // 先清空错误样式 input.style.backgroundColor = ''; // 处理空值 if (!input.value) { input.style.backgroundColor = 'red'; return false; } // 补0逻辑:长度为1时前面补0 if (input.value.length === 1) { input.value = '0' + input.value; } // 验证范围和长度 const numValue = parseInt(input.value, 10); if (numValue < 1 || numValue > 99 || input.value.length !== 2) { input.style.backgroundColor = 'red'; return false; } return true; } // Input only Numbers $('.circle input').keypress(function (event) { event = event || window.event; var charCode = event.which || event.keyCode; var charStr = String.fromCharCode(charCode); // FireFox key Del - Supr - Up - Down - Left - Right if (event.key !== undefined && event.charCode === 0) { return; } // Only allow numbers if (!/^[0-9]$/.test(charStr)) { event.preventDefault(); } }); </script>
关键改动说明
- 粘贴逻辑:用
match(/.{1,2}/g)替代原有的拆分正则,实现左到右每两位拆分;添加e.preventDefault()避免默认粘贴干扰;遍历输入框时直接调用handleChange触发验证。 - 验证函数:调整判断顺序,先清空错误样式,再处理空值,然后补0,最后验证范围和长度,逻辑更清晰;修正范围判断(原
input.value < 0.9不合理,改成numValue < 1);移除冗余的长度判断条件。 - 输入限制:简化了数字验证的正则,只允许单个数字输入,避免重复判断。
内容的提问来源于stack exchange,提问作者Freddan
相关产品推荐
相关产品推荐

