使用input.validity.valid,为什么我的数字输入在此方案中返回对值0.
有效?
<input type="number" min="1" max="999" step="1" value="0." id="one" /> <!--Valid??-->
<input type="number" min="1" max="999" step="1" value="0.0" id="two" /> <!--fine-->
<input type="number" min="1" max="999" step="1" value="0" id="three" /> <!--fine-->
Chrome 37.0.2062.103 m
修改
奇怪的是,任何带有句号结尾的负数也会破坏验证:
<input type="number" min="1" max="999" step="1" value="-14." id="one" />
答案 0 :(得分:6)
这里实际上有两个答案:
0.
之类的值无法正确验证。required
,否则该字符串被视为有效。严格地说,它是第一个引起你所看到的行为的因素,因为它阻止了#2的发生,但是如果在Chrome中修复了这个bug那么问题就在于(即只处理初始标记) ,而不是任何后续的用户互动),#2将适用。
值得注意的是,#2是导致Firefox中类似(但不完全相同)行为的原因。
#1的原因是Chrome在其rangeUnderflow
检测及其badInput
检测中使用了不同的解析算法。
rangeUnderflow
使用Decimal::fromString(...)
如果输入以NaN
结尾导致.
返回rangeUnderflow
,则返回false
:
if (!numericValue.isFinite())
return false;
相比之下,badInput
使用StringToDoubleConverter::StringToDouble(...)
基本上忽略了尾随.
,因此不会将输入视为“错误”。
根据the spec:
字符串是有效浮点数,如果它包含:
- 可选地,U + 002D HYPHEN-MINUS字符( - )。
- 以下给定顺序中的一个或两个:
醇>
- 一系列一个或多个ASCII数字。
- 单个U + 002E FULL STOP字符(。)。
- 一系列一个或多个ASCII数字。
请注意,2.2.2不是可选的 - 即如果您有.
,则必须在其后面有数字。
因此badInput
不正确。 (如果Chrome至少在将0.
视为有效时保持一致,则会检测到rangeUnderflow
但如果/当他们修复Chrome中的错误时,问题中的HTML会显示仍然显示为有效。为什么呢?
例如,如果您在HTML中设置value="aaa"
。输入仍会显示为有效,即使aaa
会导致badInput
为true
。
这是因为在解析/呈现页面时,Chrome会对属性值运行值清理算法。当它看到的值不是valid floating point number时,它必须根据the spec的要求将输入值设置为空字符串。除非输入标记为required
,否则空字符串被视为有效。目前在value="0."
的Chrome中没有出现这种情况,因为它(错误地)传递了值清理算法。但是,如果/当他们修复Chrome中的错误时,就会发生这种情况。
如果您实际在输入中键入aaa
,则会显示为无效,即badInput===true
。同样,在Firefox和Chrome中,如果/当他们修复错误时,如果您在字段中输入0.
,则会提供badInput===true
,因此valid===false
。
答案 1 :(得分:3)
在the spec中说:
用户代理不得允许用户将值设置为非空 不是有效浮点数的字符串。如果是用户代理 提供用于选择数字的用户界面,然后该值必须 被设置为代表该数字的最佳代表 用户选择的浮点数。
规范继续说:
值清理算法如下:如果值为 element不是有效的浮点数,然后将其设置为空 而不是字符串。
在Firefox中,DOM中的value
被设置为第一个输入的空字符串。这是一个有效的状态)。如果您希望第一个字段在这种情况下无效,you must make it required
:
<input type="number" min="1" max="999" step="1" value="0." id="one" required />
该规范还说:
约束验证:虽然用户界面描述了用户代理无法转换为有效浮点数的输入, 控制输入不良。
我认为在这种情况下,只要#one
输入未显示0.
值,Firefox(32.0)正在执行的操作就是正确的。在Firefox中,如果我在0.
输入中手动输入值#one
,则会将其正确突出显示为无效。
但是,在Chrome 38.0.2125.58 beta-m中,即使0.
评估为空字符串,页面加载时也会显示document.querySelector("#one").value
值。这意味着它无法被required
以及约束验证捕获。我相信这是Chrome中的一个错误。
答案 2 :(得分:0)
据我所知,验证的value
属性正在使用html5 valueAsNumber
功能进行解析。这与JavaScript有不同的规则,因此在FF32中:
var el = document.createElement("input");
el.type = "number";
el.value = "1";
el.valueAsNumber;
/*
1
*/
但
var el = document.createElement("input");
el.type = "number";
el.value = "0.";
el.valueAsNumber;
/*
NaN
*/
如果“0”因此被解析为NaN
我认为验证被绕过了。
答案 3 :(得分:0)
在输入类型编号中,包含值的内容为floating-point number。
floating-point number由以下部分组成,完全按以下顺序排列:
您可能知道浮点数0. == 0.0 == 0
。与其他人一样,0.0验证很好,因此0.
也是一个很好的验证。