为什么此输入有效

时间:2014-09-11 12:32:26

标签: javascript html5 validation

使用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

jsFiddle

修改

奇怪的是,任何带有句号结尾的负数也会破坏验证:

<input type="number" min="1" max="999" step="1" value="-14." id="one" />

jsFiddle

4 个答案:

答案 0 :(得分:6)

这里实际上有两个答案:

  1. Chrome中存在一个错误,这意味着当您在输入字段中输入/设置值时,0.之类的值无法正确验证。
  2. 如果在HTML标记中设置了无效值,则浏览器必须忽略它并将值设置为空字符串,除非该字段标记为required,否则该字符串被视为有效。
  3. 严格地说,它是第一个引起你所看到的行为的因素,因为它阻止了#2的发生,但是如果在Chrome中修复了这个bug那么问题就在于(即只处理初始标记) ,而不是任何后续的用户互动),#2将适用。

    值得注意的是,#2是导致Firefox中类似(但不完全相同)行为的原因。

    1。 Chrome错误

    #1的原因是Chrome在其rangeUnderflow检测及其badInput检测中使用了不同的解析算法。

    rangeUnderflow使用Decimal::fromString(...)如果输入以NaN结尾导致.返回rangeUnderflow,则返回false

    if (!numericValue.isFinite())
       return false;
    

    相比之下,badInput使用StringToDoubleConverter::StringToDouble(...)基本上忽略了尾随.,因此不会将输入视为“错误”。

    根据the spec

      

    字符串是有效浮点数,如果它包含:

         
        
    1. 可选地,U + 002D HYPHEN-MINUS字符( - )。
    2.   
    3. 以下给定顺序中的一个或两个:   
          
      1. 一系列一个或多个ASCII数字。
      2.   
        1.   
        2. 单个U + 002E FULL STOP字符(。)。
        3.   
        4. 一系列一个或多个ASCII数字。
        5.   
      3.   
    4.   

    请注意,2.2.2不是可选的 - 即如果您有.,则必须在其后面有数字。

    因此badInput不正确。 (如果Chrome至少在将0.视为有效时保持一致,则会检测到rangeUnderflow

    2。标记与用户输入

    如果/当他们修复Chrome中的错误时,问题中的HTML会显示仍然显示为有效。为什么呢?

    例如,如果您在HTML中设置value="aaa"。输入仍会显示为有效,即使aaa会导致badInputtrue

    这是因为在解析/呈现页面时,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由以下部分组成,完全按以下顺序排列:

  1. 可选地,第一个字符可以是“ - ”字符。
  2. “0-9”范围内的一个或多个字符。
  3. 可选地,以下部分,完全按以下顺序:
    1. a“。”字符
    2. 范围“0-9”
    3. 中的一个或多个字符
  4. 可选地,以下部分,完全按以下顺序:
    1. “e”字符或“E”字符
    2. 可选地,“ - ”字符或“+”字符
    3. “0-9”范围内的一个或多个字符。

  5. 您可能知道浮点数0. == 0.0 == 0。与其他人一样,0.0验证很好,因此0.也是一个很好的验证。