html - 为什么我的 HTML 数字输入卡在步骤 0.010000000000000009 上?
问题描述
当我<input type="number"/>
使用step="0.010000000000000009"
. 我只能单击按钮增加值一次以填充min
值,然后第一次增加步长值,然后它会卡在这个值上,进一步点击没有效果。我只能用min="1.2" max="1.3"
.
,的所有其他组合min
,我尝试允许多次单击该按钮,直到它在定义的步骤中达到最大值。max
step
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>input with decimal step</title>
</head>
<body>
<input type="number" min="1.2" max="1.3" step="0.010000000000000009"/>
</body>
</html>
解决方案
我相信,根据 HTML5 Living Specification,您的<input />
元素“遭受步骤不匹配”:
- https://html.spec.whatwg.org/multipage/input.html#the-step-attribute
- https://html.spec.whatwg.org/multipage/input.html#concept-input-min-zero
遵循您的案例的规范...
step
值为0.010000000000000009
(来自)parseFloat
。step-scale-factor
价值1
永远为<input type="number" />
是属性,
step-base
即。min
1.2
allowed-value-step
是step
*step-scale-factor
是1 * 0.010000000000000009 === 0.010000000000000009
. _回复:“约束验证”,规范说:
约束验证:当元素有一个
allowed-value-step
, 并且对由元素给出的字符串应用 the-algorithm-to-convert-a-string-to-a-number 的结果value=""
是一个数字,从 中减去的数字step-base
不是的整数倍allowed-value-step
,该元素正遭受阶跃不匹配。我将把它改写成这个......:
- 如果元素具有
allowed-value-step
和数字value=""
属性。- (所以这只有在非空之后,
<input/>
比如点击一次向上/向下按钮给它一个值1.2
) - ...然后从 (the ) 中减去
1.2
( thestep-base
)得到。1.2
value=""
0
- 并且
0
不是的整数倍0.010000000000000009
。 - 因此,该元素正遭受步不匹配。
- (所以这只有在非空之后,
- 如果元素具有
现在,写下你的发现:
我只能点击按钮增加一次数值填入
min
数值
是的,这遵循 HTML5 规范:初始value=""
值为空,因此浏览器将选择下一个有效的最大值,即该min="1.2"
值。
然后只有一次第一次增加步长值
是的,那是因为下一步是-两个浏览器都将显示截断为,但是一旦发生这种情况,我们就会看到浏览器行为的不同:1.2 + 0.010000000000000009
1.210000000000000009
1.21
- Firefox 似乎正确地遵守了规范
HTMLInputElement.validity.stepMismatch
,true
并且由于步进不匹配条件,它设置 并禁用了向上/向下按钮。 - Chrome 92 没有,使用向上/向下按钮设置其他值仍然会导致
HTMLInputElement.validity.stepMismatch === false
.
这是一个显示有效性信息的片段:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>input with decimal step</title>
</head>
<body>
<input id="inp" type="number" min="1.2" max="1.3" step="0.010000000000000009" />
<ul id="eventsList"></ul>
<script>
const inp = document.getElementById('inp');
const ul = document.getElementById('eventsList');
inp.addEventListener( 'input', logInfo );
inp.addEventListener( 'change', logInfo );
inp.addEventListener( 'click', logInfo );
function logInfo( e ) {
const li = document.createElement('li');
li.textContent = e.type + ". Value: " + inp.value + ", valid: " + inp.validity.valid + ", stepMismatch: " + inp.validity.stepMismatch;
ul.appendChild( li );
}
</script>
</body>
</html>
- 在 Chrome 中,它让我在停止之前单击向上按钮 10 次(
1.2
,1.21
,1.22
,1.23
, ...,1.28
, to1.29
),尽管它从不报告stepIsmatch: true
。 - 在 Firefox 中,它让我在设置之前单击向上按钮 1 次(
1.2
和1.21
)stepMismatch: true
。
鉴于他们对规范的解释(或至少是他们的实施)更宽容,并且当设置为奇怪的值时不太可能导致最终用户的挫败感,因此我的钱花在了 Chrome 上做他们自己的事情。step
有趣的是,Number
浏览器中的类型似乎能够在0.010000000000000009
没有任何迹象的 IEEE 754 舍入(Python 同上)的情况下准确表示,而 C#/.NET 的Single
(32 位)和Double
(64 位)浮点类型既窒息又给出我相当糟糕的近似值。
推荐阅读
- javascript - 为什么当我访问我的网站时,我的数据没有在正确的时间使用 EJS 呈现?
- javascript - 将闹钟添加到待办事项列表
- laravel-8 - 从控制器重定向时将片段保留在 URL 中
- javascript - 无法部署 Heroku 应用程序(npm err!ELIFECYCLE 退出状态 1)
- python - AttributeError:模块“django.db.models”没有属性“RESTRICT”
- .net - Azure Function App 与 Azure Web App 服务的运行时堆栈
- php - 如何使 cURL 与 php 变量一起使用
- python - 创建元素列表并在字典的不同键上获取匹配元素
- xcode - 为什么架构 arm64 的未定义符号:_XML_ErrorString + 其他 _XML_*?
- r - 将日期序列传递给数据框列