输入框onChange格式化数值时光标自动跳转至末尾问题求助
千分位输入框光标错位修复方案
问题根因
- 原修复方案直接复用格式化前的光标索引值,未考虑格式化操作会在字符串中新增千分位逗号,导致格式化后的实际光标位置与预期产生偏移
requestAnimationFrame的执行时机没有问题,核心错误点为光标位置的计算逻辑
具体修复步骤
步骤1:格式化前统计光标前的有效数字个数
在触发输入事件后、执行格式化逻辑前,先统计当前光标左侧的纯数字数量(过滤已存在的千分位逗号):
const element = event.target; const rawValue = element.value; const currentCaretPos = element.selectionStart; // 统计光标前的有效数字个数,排除逗号干扰 const digitCountBeforeCaret = rawValue.slice(0, currentCaretPos).replace(/,/g, '').length;
步骤2:执行数值格式化
直接使用你现有的formatValue函数处理输入值即可,无需修改原有格式化逻辑:
const formattedValue = formatValue(rawValue); element.value = formattedValue;
步骤3:反推格式化后的正确光标位置
遍历格式化后的字符串,根据之前统计的有效数字个数,匹配得到对应的光标位置:
let newCaretPos = 0; let countedDigits = 0; while (newCaretPos < formattedValue.length && countedDigits < digitCountBeforeCaret) { // 仅统计数字,千分位逗号不计数 if (/\d/.test(formattedValue[newCaretPos])) { countedDigits++; } newCaretPos++; } // 赋值正确的光标位置 window.requestAnimationFrame(() => { element.selectionStart = newCaretPos; element.selectionEnd = newCaretPos; });
边界适配说明
- 若存在小数位需求,统计
digitCountBeforeCaret时无需过滤小数点,现有规则已自动兼容小数位场景的光标定位 - 该逻辑同时适配输入、删除两种操作场景,无论格式化后新增或减少了千分位逗号,都可以准确定位光标
修复后即可解决如下偏移问题:
内容的提问来源于stack exchange,提问作者Arunkumar Subramani
相关产品推荐
相关产品推荐

