注意:自本答案撰写以来,#1中提到的Chrome错误已经修复,因此现在仅适用于#2。
实际上有两个答案:
1. Chrome 中存在一个错误,这意味着当您在输入字段中输入/设置类似于 0. 的值时,无法正确验证。
2. 如果在 HTML 标记中设置无效值,则浏览器需要忽略它并将该值设置为空字符串,除非该字段标记为“required”,否则该值被视为有效。
严格来说,正是第一个原因导致了您所看到的行为,因为它阻止了#2的发生,但如果在 Chrome 中修复了该错误,则只需处理初始标记(而不是任何后续用户交互),#2 将适用。
还值得注意的是,#2 是导致 Firefox 中类似(但不完全相同)行为的原因。
1. Chrome 错误
rangeUnderflow
使用 Decimal::fromString(...)
,如果输入以 .
结尾,则返回 NaN
,导致 rangeUnderflow
返回 false
:
if (!numericValue.isFinite())
return false
相反,
badInput
使用
StringToDoubleConverter::StringToDouble(...)
,它基本上忽略了一个尾随的
.
,所以输入不被视为“坏的”。
根据
规范:
一个字符串是一个有效的浮点数,如果它包含以下内容:
- 可选的,一个U+002D连字符字符(-)。
- 以下一项或两项中的一项,按给定顺序:
- 一个或多个ASCII数字的系列。
-
- 一个单独的U+002E句点字符(.)。
- 一个或多个ASCII数字的系列。
请注意,2.2.2不是可选的 - 也就是说,如果你有一个
.
,你必须在它后面加上数字。
所以错误的是
badInput
。(如果Chrome至少对待
0.
作为有效的是一致的,那么就会检测到
rangeUnderflow
)
2.标记与用户输入
例如,如果在HTML中设置
value="aaa"
。即使
aaa
会导致
badInput
为
true
,输入仍将显示为有效。
这是因为在解析/渲染页面时,Chrome会对属性值运行一个
值净化算法。当它看到一个不是
有效的浮点数的值时,必须按
规范要求将输入的值设置为空字符串。除非输入被标记为
required
,否则空字符串被认为是有效的。目前,在Chrome中对于
value="0."
,它(错误地)通过了值净化算法,因此不会发生这种情况。但是,如果/当他们在Chrome中修复了这个错误,这就是你所期望发生的事情。
如果您在输入框中实际键入
aaa
,则它将显示为无效,即
badInput===true
。同样,在Firefox中以及在Chrome中(如果/当他们修复了此错误),如果您在字段中键入
0.
,它将给出
badInput===true
,因此
valid===false
。
pattern
属性 - 它会被忽略。 - CodingIntrigue