SSN输入框Delete键失效,如何兼顾自动格式化与按键正常功能
问题原因
- 现有
keypress监听逻辑会拦截所有非数字输入,Delete、方向键这类功能键生成的字符无法通过数字校验,默认行为被直接阻止,所以按Delete没有删除效果 - 自动格式化逻辑直接覆盖
input.value后,会将输入光标强制重置到字符串末尾,就算删除成功也会出现光标错位的问题,影响使用体验
修复后代码
// SSN校验:仅允许数字输入,同时放行功能键 $('input.ssn').on('keypress', function(event) { // 放行所有常用功能键:Delete、退格、方向键、Tab、回车等 const allowedKeyCodes = [8, 9, 13, 37, 38, 39, 40, 46]; if (allowedKeyCodes.includes(event.which)) { return true; } // 仅校验可打印字符是否为数字 var character = String.fromCharCode(event.which); if (!isInteger(character)) { return false; } }); // 整数校验逻辑保持不变 function isInteger(s) { if (s === '-') return true; var isInteger_re = /^\s*(\+|-)?\d+\s*$/; return String(s).search(isInteger_re) != -1 } // SSN格式化:新增光标位置保持逻辑 $('input.ssn').on('keyup', function() { // 记录格式化前的光标位置 const cursorPos = this.selectionStart; const oldVal = this.value; var val = this.value.replace(/\D/g, ''); var newVal = ''; if ((val.length > 3) && (val.length < 6)) { newVal += val.substr(0, 3) + '-'; val = val.substr(3); } if (val.length > 5) { newVal += val.substr(0, 3) + '-'; newVal += val.substr(3, 2) + '-'; val = val.substr(5); } newVal += val; this.value = newVal; // 修正光标位置:如果格式化前光标不在末尾,调整到对应位置 if (cursorPos !== oldVal.length) { // 计算新的光标位置:统计光标前新增的横杠数量 const addedDashCount = (newVal.slice(0, cursorPos).match(/-/g) || []).length - (oldVal.slice(0, cursorPos).match(/-/g) || []).length; this.setSelectionRange(cursorPos + addedDashCount, cursorPos + addedDashCount); } });
修改点说明
- 给
keypress监听新增了功能键放行逻辑,Delete、方向键、退格等常用控制键不会被拦截 - 格式化逻辑新增了光标位置适配,自动格式化后不会强制把光标跳到末尾,保留用户之前的输入位置
- 原有SSN自动格式化规则、数字输入限制逻辑完全保留,不会影响现有功能
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

