在这个系列,我将会向你展示两种轻量级方法来验证前端的表单。这两个方法都集合了较新的web API。随后,我也会向你介绍如何使IE9以下版本的浏览器也支持这些API。(这会为你提供全球网络流量99.6%的覆盖率).
最后,我们来看一下MailChimp的注册表单,并用少于28行的代码来实现它。
注意,前端进行的表单验证是可以被绕过的,因此你需要在服务器端再次进行验证。
好了,让我们开始吧。
###文章系列:
在HTML中的约束验证 (你现在正在阅读此篇)
The Constraint Validation API in Javascript
A Validity State API Polyfill
Validatiing MailChimp Subscribe Form
最简单的验证方法: 约束验证
通过输入类型(例如,)以及验证属性(例如required和patten), 浏览器可以自行对用户输入的内容进行验证,以及在输入内容不符合验证规则时发出警告。
想要查看浏览器支持的输入类型以及属性可以查看这篇文章varies wildly from browser to browser, 不过, 我也会提供一些技巧和方法来最大化的保证浏览器的兼容性。
基础的文本验证
假设你有一个文本字段,用户在提交表单之前必须要填充这个字段. 这时可以给输入框添加 required 属性,当用户没有填充此字段时,支持该属性的浏览器就会发出警告,并阻止表单的提交。
``
拥有required属性的文本框在chrome浏览器下的显示。
你需要设置输入内容的字数的最大或最小限制吗? 使用 minlength 和 maxlength 属性可以做到这一点。下面这个例子就展示了限制输入内容的长度在3-12个字符内
``
当输入的字符长度不在所规定的范围内,在Firefox浏览器下就会显示此错误信息。
pattern 属性允许你定义一个正则表达式对所输入的内容进行验证。例如,假设你规定输入的密码必须包含一个大写字符,一个小写字符以及一个数字。浏览器会根据正则表达式对所输入的内容进行验证
``
当输入的密码不符合规定时在Safari浏览器下会显示此错误信息。
如果你在定义了pattern的同时也定义了title属性,那么当正则表达式匹配不成功时title属性的值会包含在错误信息提示框内。
``
在 Opera浏览器下显示的错误信息提示框, 其中包含title属性的值,可以以此来作为正则表达式的补充说明。
你也可以结合 minlength和 (银行似乎就是这样, maxlength) 给输入的内容设定一个最小或最大的长度值。
``
查看 Chris Ferdinandi的演示 Form Validation:Basic Text (@cferdinandi)在 CodePen上。
####验证数字
number输入类型只允许用户输入数字。浏览器会拒绝接收字母或者其他的字符,以及在用户使用它们的时候发出警告。浏览器支持input[type=""number""], 但是你也可以提供一个pattern作为备用。
``
默认情况下, number 类型的输入框只允许输入整数。
你也可以通过设置step 属性来允许接收浮点数 (数字与小数) 。告诉浏览器你想接收的数字间隔。这个间隔可以是任何数值 (例如, 0.1 ), 或者设置为 any 如果你想接收任何数字的话。
你可以通过pattern来设置允许接收的位数。
``
如果想要给输入的数字设定范围, 可以通过设置min和max属性让浏览器来验证. 你可以修改你的pattern去进行匹配.例如,假设输入的数字在3和42之间, 你可以这样做:
``
查看Chris Ferdinandi的演示 Form Validation: Numbers (@cferdinandi) 在 CodePen上。
验证Email地址和URL
email输入类型会在用户输入不合法的Email地址时给出警告 。像number输入类型一样, 你需要给浏览器提供一个pattern来告诉浏览器不支持哪些输入类型。
Email 验证的正则表达式一直以来都是个热议话题。为了寻找符合RFC822规范的,我测试了许多正则表达式。下面使用的这个,由 Richard Willis所写, 是我发现的最好的一个。
``
email输入类型允许email地址没有TLD ( ""email@example.com""中的 ""example.com""). 这是由于email地址规范RFC822, 允许本地电子邮件不需要顶级域名。
如果你想要接收TLD (你可能会这么做),你可以修改pattern强制规定输入的email地址需要 域名扩展,就像下面这样:
``
同样的,url输入类型会在用户输入不合法的URL地址时给出警告。不过, 你应该为那些不支持url类型输入框的浏览器提供一个pattern.下面使用的这个pattern改编自Diego Perini的一个项目, 是我迄今为止遇到的最强大的一个。
``
像email输入类型一样,url也允许不输入TLD.如果你不想接收本地URL , 你可以更新pattern来检查TLD , 就像这样。
``
查看 Chris Ferdinandi的演示Form Validation: Email & URLs(@cferdinandi) 在CodePen上.
验证日期
这有一些非常酷的输入类型,不但可以验证日期而且可以提供原生的日期选择器. 不幸的是, 只有Chrome, Edge, 和 Mobile Safari 支持这个属性. (我已经期待了Firefox支持这个功能好多年了 更新: 这个功能有希望在不久的将来被 Firefox 支持) 其他的浏览器只会将它视为一个文本域进行显示.
一如既往, 我们可以为不支持该类型的浏览器提供一个pattern .
date 输入类型的格式是标准的日/月/年。
``
在支持该类型的浏览器中, 选定的日期会显示成这样:MM/DD/YYYY(注意:这是处于美国所显示的格式.其他国家/地区的用户以及修改日期设置的用户的显示可能会有所不同)。但是value实际上是这种格式:YYYY-MM-DD。
你应该为使用不支持该类型输入框的浏览器用户提供一个指导,像这样, ""请使用 YYYY-MM-DD 格式."" 然而, 你并不想要那些使用Chromn或 Mobile Safari的用户看到这个提示 , 因为这并不是他们会看到的格式, 这样会造成困扰。
查看Chris Ferdinandi关于 [Form Validation: Dates]的演示(codepen.io/cferdinandi…) (@cferdinandi) 在CodePen上.
一个简单的功能测试
我们可以写一个功能测试来检测该输入类型的支持情况. 我们可以创建一个input[type=""date""] 元素, 并为其添加一个不合法的日期值, 观察浏览器是否会对此采取措施 。然后,你可以隐藏支持date 输入类型的浏览器所显示的描述性文字 。
Date YYYY-MM-DDD
查看 Chris Ferdinandi关于Form Validation:Dates with a Feature Test]的演示(codepen.io/cferdinandi…) (@cferdinandi) 在CodePen上。
其他的日期类型
time 输入类型可以让用户选择一个时间,而 month输入类型可以让他们从年月选择器中选择月份 .再次强调, 我们需要为那些不支持这些输入类型的浏览器提供一个pattern。
time输入以12小时 am/pm 的格式进行显示, 但是value是24小时制时间格式。month输入在支持它的浏览器上以May 2017的格式进行显示,但是值是YYYY-MM格式。
就像input[type=""date""], 支持这些类型的浏览器会隐藏格式,因此你应该提供一个格式描述
查看Chris Ferdinandi的演示 Form Validation: Add novalidate programatically (@cferdinandi) 在 CodePen上。
这看起来非常容易.卖什么关子啊?
尽管这些约束验证的API非常简单并且轻量级, 但它仍然具有一些缺点
你可以通过:invalid 伪选择器对出现错误的域设置样式, 但是,你不能对错误信息设置样式.
各浏览器间的行为也不一致. Chrome浏览器在你提交表单之前不会显示任何错误信息 . Firefox 浏览器会在该域失去焦点时显示一条红线,但是只有在用户鼠标悬停在此域上时才会显示错误信息 (基于 WebKit的浏览器会一直保持错误)。
Christian Holst 和 Luke Wroblewski (这是分开的) 的用户发现,当离开一个字段时会显示错误信息,并且浏览器保持该错误,直到这个字段的问题被修复, 这提供了最好和最快的用户体验. 额外的 CSS 技巧: 只有在这些字段当前不处于编辑模式时利用invalid选择器来为它们设定样式 :not(:focus):invalid { }。
不幸的是,默认情况下,所有的浏览器都不会正常的运行。
在这个系列的下一篇文章中, 我会向你展示如何利用原生的约束验证API以及一点JavaScript来实现我们想要的用户体验。没有第三方库的引入!
转自公众号:前端留学生