代码之家  ›  专栏  ›  技术社区  ›  Xhynk

设置格式化值分隔符函数

  •  0
  • Xhynk  · 技术社区  · 5 年前

    我有这个函数可以将字符串修改为类似美元的格式

    function formatAmount(el){
      var val    = el.value;
    
      //Only Numbers
      val = val.replace(/[^0-9]/gi, '');
    
      // Pad with Zeros
      val = val.padStart(3,0);
      
      // Value with Period
      val = val.slice(0, -2) + '.' + val.slice(-2);
      
      // Append $
      val = '$' + val;
      
      console.log( val );
      //el.value = val; // Breaks??
    }
    <input type="text" onkeyup="formatAmount(this);" />

    格式化值时,它工作得很好:键入 12345 输入将记录 $123.45 .只要我用 el.value = val; 函数似乎有点奇怪,我不太明白为什么。 12345年 现在返回 $0123.45 如果你打字快或 $00123.45 如果你打字慢。为什么在更改字段值时要将0附加到字符串,而在不更改的情况下记录该值时不附加?


    编辑:

    根据@dennis所提到的,只要超时足够高,将它包装在一个输入超时函数中似乎可以工作。 10ms 不起作用,但是 100ms 似乎?不过,这看起来不太优雅:

    var formatTimeout = null;
    
    function formatAmount(el){
        clearTimeout(formatTimeout);
        formatTimeout = setTimeout(function(){
            var val     = el.value;
    
            //Only Numbers
            val = val.replace(/[^0-9]/gi, '');
    
            // Pad with Zeros
            val = val.padStart(3,0);
    
            // Value with Period
            val = val.slice(0, -2) + '.' + val.slice(-2);
    
            // Append $
            val = '$' + val;
    
            //console.log( val );
            el.value = val; // Breaks??
        }, 100);
    }
    
    5 回复  |  直到 5 年前
        1
  •  2
  •   Thomas Sauvajon Tony Garrido    5 年前

    每次按键都会触发此功能。

    如果输入12345,它将被触发5次。 如果输入速度足够慢,您的值将如下所示:

    1, the function will change it to $0.01
    2, it gets added at the end of the existing string to make it $0.012, which gets formatted by the function as $00.12
    3, the initial string will be $00.123, and it will get formatted as $001.23.
    ...
    

    最终结果将是$00123.45。

    有几种方法可以解决这个问题。最简单的解决方案是在用零填充之前修剪最初的0以保持数字的整洁。

        2
  •  1
  •   SerShubham    5 年前

    结果之间的差异 console.log 而实际的赋值是因为 formatAmount 功能每次都不同。

    当您设置输入字段的值时,就会发生这种情况;

    -> User enter `1`
    -> formatAmount takes the value, converts it to $0.01 and *sets the value* to the input box
    -> user enter `2`
    -> formatAmount takes the value ($0.012), converts it to $00.12 and *sets the value* to the input box
    

    这一直持续到你完成 12345 得到$00123.45。这是因为两个人 0 你在一开始就加上的,在第一个之后永远不会消失。 1 已键入。

    也, 控制台日志 因为每次收到的价值 1个 ,请 12 ,… 12345年 .对于这些来说,逻辑是可行的。只有当设置回值时才会失败

        3
  •  0
  •   weegee Chinnon Santos    5 年前

    javascript中的键控操作似乎工作正常。测试了不同的速度和工作像一个魅力。另外,尝试粘贴数字并使用regex删除前导0

    var textInput = document.getElementById('hello');
    textInput.onkeyup = function (e) {
        formatAmount(textInput.value);
    };
    
    function formatAmount(el){
      var val    = el;
    
      //Only Numbers
      val = val.replace(/[^0-9]/gi, '');
    
      // Pad with Zeros
      val = val.padStart(3,0);
      // replace leading 0's 
      val = val.replace(/^0+/, '');
      // Value with Period
      val = val.slice(0, -2) + '.' + val.slice(-2);
      
      // Append $
      val = '$' + val;
      
      textInput.value = val;
    }
    <input type="text" id="hello" />
        4
  •  0
  •   connexo    5 年前

    只是为了显示另一个起点,使用 Intl.NumberFormat.prototype.format() .请随时根据您的要求进行调整。

    function formatAmount(el){
      el.value = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumIntegerDigits: 3 }).format(parseFloat(el.value.indexOf('$') === 0 ? el.value.substr(1) : el.value));
    }
    <input type="text" onblur="formatAmount(this);" />
        5
  •  -1
  •   Dennis    5 年前

    我猜您的函数在同一时间执行了多次,第一次执行甚至在下一次执行开始之前都没有完成。您需要检查函数是否已经在运行。