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

价格本地化格式化输入框JS故障求助:输入内容被异常覆盖

问题原因分析

你的代码出现两个核心问题:

  1. 光标位置丢失:每次格式化后直接设置输入框值,光标会自动跳转到开头。当输入到2 222后继续输入,光标回到开头,你看到的第一个字符2误以为输入框内容变成了2,实际值是正确的22 222,只是光标位置错误。
  2. 事件选择不当:使用keyup事件无法覆盖所有输入场景(比如粘贴、右键菜单输入),且频繁修改输入框值会干扰onchange事件的触发逻辑——浏览器会认为值一直在变化,失去焦点时无法检测到“最终变更”。

另外,parseInt会截断小数,若后续需要支持带小数的价格,会存在兼容性问题,建议改用Number()处理数字转换。

修正后的代码

HTML(保持不变)

<input type="text" placeholder="Minimum price" name="minPrice" id="minPrice" value="">

JavaScript

const minPrice = document.getElementById('minPrice');

minPrice.addEventListener('input', function(e) {
  // 提取所有数字字符(如需支持小数,可修改正则为 /[^\d.]/g)
  const rawValue = e.target.value.replace(/[^\d]/g, '');
  
  // 空输入直接清空
  if (!rawValue) {
    e.target.value = '';
    return;
  }

  // 转换为数字并格式化为法语本地化格式
  const num = Number(rawValue);
  const formattedValue = num.toLocaleString('fr-FR');

  // 计算格式化后的光标位置,避免光标跳转到开头
  const originalCursorPos = e.target.selectionStart;
  const digitsBeforeCursor = e.target.value.substring(0, originalCursorPos).replace(/[^\d]/g, '').length;
  
  let newCursorPos = 0;
  let digitCounter = 0;
  
  // 遍历格式化后的字符串,找到对应光标位置
  for (let i = 0; i < formattedValue.length; i++) {
    if (/\d/.test(formattedValue[i])) {
      digitCounter++;
      if (digitCounter === digitsBeforeCursor) {
        newCursorPos = i + 1;
        break;
      }
    }
  }
  
  // 如果光标原本在末尾,直接设置到格式化后字符串的末尾
  if (digitsBeforeCursor === rawValue.length) {
    newCursorPos = formattedValue.length;
  }

  // 更新输入框值并恢复光标位置
  e.target.value = formattedValue;
  e.target.setSelectionRange(newCursorPos, newCursorPos);
});
关键改进点
  • 使用input事件:覆盖所有输入场景(键盘输入、粘贴、拖拽等),比keyup更可靠。
  • 光标位置维护:计算格式化前后的数字位置对应关系,确保光标始终在用户输入的位置附近,避免体验混乱。
  • 鲁棒的数字提取:用正则过滤非数字字符,避免格式化时出现异常。
  • 兼容后续扩展:如需支持小数,只需修改正则表达式保留小数点即可。

内容的提问来源于stack exchange,提问作者Wikke

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 18:39:58