浏览器输入类型=数字微调器是如何工作的



我正在尝试复制创建输入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

来自HTML标准

当元素出现步骤不匹配时,用户代理可能将元素的值四舍五入到元素所对应的最接近的数字不会受到阶跃失配的影响。如果存在两个这样的数字,鼓励用户代理选择最接近正无穷大的一个。

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

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

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

最新更新