【坑】<input> 的「type="number"」

1,529 阅读3分钟

正文

在你处理「只允许输入0-9数字」的需求的时候,你可能很容易想到<input>标签的type="number"。于是乎,你就这么干了。通常,你会在键盘上乱输入一通(比如,依次输入“a,b,c,d,e,f.....”)来进行测试。这时候,你很有可能发现,基本上所有的字符都不能输入(这是符合预期的),但是为唯独一个英文字母“e”可以输入。此时,你心里面可能会有无数只草泥马奔腾而过,这是什么鬼?你的直觉告诉你,这肯定是 bug。假如,你相信你的直觉,并且,你恰好是工作在基于原生<input>标签来封装而成的组件上(比如说,antd 的<Input> 组件),那么,你极有可能一头扎进该组件的源码进行 debug。如此一来,你就在错误的方向上做着错误的事,最终与事实的真相南辕北辙了。

事实上,真相是极其残酷的 - 这不是 bug,这是一个遵循 W3C 标准的实现。“允许输入英文字母“e””,这是相当违反开发者直觉的(不过,从侧面来看,直觉也是不靠谱的)。所以,称之为「坑」也算名副其实了。

那么,下面我们来研究一下,在 W3C/whatwg 标准中,对于实现<input>标签的type="number"功能,看看它是怎么说的?

image.png 那什么是一个「合法的浮点数」呢?我们点进去,只见标准规范文档如是说道:

image.png

上面这段话,翻译成更通俗易懂的表述如下:

一个代表合法的浮点数的字符串由以下部分(按照书写顺序)组成:

  1. 可选的,以一个“-”(英文的减号)开头;
  2. 后面跟着一个或者多个0-9的数字;
  3. 可选的:
    1. 一个“.”字符,代表数字点;
    2. 后面跟着一个或者多个0-9的数字;
  4. 可选的:
    1. 一个“e”或者“E”字符;
    2. 可选的,一个“-”或者“+”字符;
    3. 一个或者多个0-9的数字;

所以,看到这里,你应该明朗了。实际上,这里允许输入的“e”字符就是我们科学记数法里面的“e”(具体含义是:以“10”为底数的幂),而<input>标签的type="number"的标准规范中明确指出了,这里的「number」是包括了用科学记数法来表示的数值。

总结

通过踩过这个坑后,深刻地明白了<input>标签的type="number"确切含义 - 「数值类型的值」既然是数值类型,那么当前包括整数,浮点数,只是大部分人都想不到还有一个科学计数法而已。如此看来,它其实是不能精确满足我们「只允许输入0-9数字」这个开发需求的。如果要实现这个需求,恐怕,我们要自己监听<input>标签的change事件,然后用正则表达式/^\d*$/来阻止非法字符的输入了。

参考资料