【问题标题】:How the browser input type=number spinner works?浏览器输入 type=number 微调器如何工作?
【发布时间】:2020-08-27 09:31:57
【问题描述】:

我正在尝试复制创建 input type=number 时获得的微调器的功能。

<input type=number step=0.3/>

在这种情况下,单击上方的微调器会使值增加 0.3(0.3、0.6、0.9、1.2、1.5 ...等)。

但是当input字段的值为1.4并且我点击增加按钮时值变为1.5 所以只增加了0.1,当输入字段的值为1.3时增加了0.2。 我的问题是如何计算出当前值增加了多少以匹配最接近的步进增量?!

这是我的尝试

export class Spinner { 
        increase(currentValue, step) {
           const step = step || 1;
           const decimalSize = getDecimalSize(step);
           const current = normalize(currentValue, decimalSize);
           const ratio = Math.ceil(normalize(current / step, decimalSize));
           let increment = normalize(ratio * step, decimalSize);
         
        if (
            normalize(current % step, decimalSize) === 0 ||
            current === increment ||
            normalize(current % step, decimalSize) === 1
        ) {
            increment = normalize(current + step, decimalSize);
        }
    }
}

export function getDecimalSize(value: number) {
    if (Math.floor(value) === value) return 0;
    return value.toString().split(".")[1]?.length || 0;
}

export function normalize(value: number, decimalSize: number): number {
    decimalSize = decimalSize || 1;
   const n = Math.pow(10, decimalSize + 1);
   return Math.round(value * n) / n;
}


这适用于正数,但不适用于负数

例如,如果当前值是-2 并且步长是0.3 我得到-1.8 而不是-1.7

【问题讨论】:

    标签: javascript math


    【解决方案1】:

    来自HTML Standard

    当元素遇到步骤不匹配时,用户代理可能 将元素的值四舍五入到最接近的数字 不会遭受步骤不匹配的影响。如果有两个这样的数字, 鼓励用户代理选择最接近的正无穷大。

    您的用户代理 (~browser) 可能会舍入该步骤以避免不匹配。它从 1.4 变为 1.5,因为 1.5 距离 0 正好 5 步,而 1.7 距离 5.666 步。同样的道理也适用于负数,1.8 可以被 0.3 整除,而 1.7 则不能。

    请注意,在第一种情况下,1.8 会比 1.5 更接近四舍五入,这违反了规范。这些事情发生了,而且将来可能会发生变化。

    我还没有尝试过,但我想你可能会在其他一些浏览器中得到不同的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-13
      • 2016-05-20
      • 2017-09-01
      • 2014-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多