You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

输入框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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 05:39:00