如果你想验证表单输入是否有效,比如你想让输入框只接受整数,而不是小数或文字,在 HTML5 中你可以用以下代码轻松实现:
<input type="number" pattern="[0-9]*" />
但是,用户仍然可以输入无效信息:
- 在 Firefox 里,你可以输入任何字符:比如“fsielfs”。
- 在 Chrome 里,你可以输入一些无效的数字:比如“1..2.2.2”。
输入框会显示为错误状态,但是如果你覆盖了原生样式就不会看到这个效果了。你需要用 :invalid
选择器来定义错误样式:
input[type="number"]:invalid {
border-color: red;
}
但是对 JavaScript 来说,它几乎是一个黑箱:
- 无效输入不会触发
change
事件。 - 当输入无效时,
value
返回空字符串 。 validity
属性只能告诉你输入是否有效,而不能提供原始输入值。
也就是说,JavaScript 无法知道用户的错误输入,也无法更改它们。为什么会这样?
当你指定 type="number"
和 pattern="[0-9]*"
时,你将表单格式验证的工作交给了浏览器。当输入无效时,浏览器会提醒并要求用户修正。JavaScript 可以检查 e.target.validity
来了解输入是否有效,但无法了解更多细节。HTML 表单验证对屏幕阅读器非常友好,也很易于使用,是 Web 标准的一部分。而 JavaScript 验证则难以做到这一点。
但是如果我们仍然想要用 JavaScript 来验证和过滤输入……
解决方案 1:用 type="text"
。
这样你就可以捕获所有字符输入了。你可以在 change
事件中验证和修订 e.target.value
。这是最简单全能的方法。
缺点便是失去了系统对输入类型的优化。尤其是在移动设备中,会弹出标准键盘,而不是数字键盘。用户的输入步骤会更加繁琐,影响体验。
解决方案 2:监听 input
事件。
和 change
事件不同,只要用户输入了内容,不管有效无效,都会触发input
事件。你可以检查 e.data
属性存储输入值。
但它也不是万能的。e.data
得到的只是本次输入的字符,你并不知道光标在哪里,所以不能准确得到完整输入。加入用户按了删除键,你不知道他删除了哪里的多少字符。因此这个方法具有很大的局限性,并不是 100% 可靠。
加入你只要对单个输入字符进行逐一检查,而不需要考虑整体有效与否,那么用这种方法是可以的。在一些情况下,你需要保证每次输入后都是有效状态,可以和 change
事件组合使用,保存每个有效状态,一旦遇到无效输入状态,则退回上一个有效状态。但是,很多输入的中间状态可能是无效的,比如电子邮件,这种情况就不能用 input
事件来解决。
注意:不要用 keydown
或 keyup
事件,因为它们只检测键盘事件,而输入可能是由复制粘贴,语音输入或虚拟键盘实现的,而不会触发这些键盘事件。
总结一下,确实你可以只用 JavaScript 去验证表单输入。但是我并不推荐这样做。以上两种解决方案都有限制,而且不符合 Web 标准的原则。结合 HTML 和 JavaScript 表单验证,效果会更好。
发表回复