HTML5表单验证的例子

时间:2022-06-03 07:55:51

原文地址:The Art Of Web
无责任翻译:Sekai


假设咱要使用纯HTML加一点CSS来完成或者辅助那些Javascript表单验证,这在最近简直无法想象。当然,坊间还是出现了各种奇葩的插件来实现这些目标,然而还是没有一个具体的唯一的标准让我们来参照使用。

为了了解更详细的有关HTML5表单验证的知识,你可以在下文的引用链接中找到一些更屌的文章。在本文中,我们只打算介绍几个最简单的例子,这些例子涵盖了一些最基本的元素。

当然我知道你要问什么,本文中的例子当前可以运行在以下浏览器:Safari 5,Chrome 6,Opera 9,Firefox 4 Beta以及iPhone/iPad。当然每个浏览器的默认行为有所差异。

1. ‘required’属性

首先对你的表单所能进行的最简单的改造就是对文本域表单加上’required’属性:

<input type="text" name="name" required>

这将提醒这幫子浏览器,这个文本域的值是强制输入的。不同的浏览器可能通过不同的形式来呈现,例如Firefox 4 Beta默认会加上一个红色的阴影框,Opera会显示一个警告,甚至会禁止表单的提交,希望未来这些行为能得到统一。

在这些例子中,原文他们使用CSS来覆盖这些浏览器默认行为,这就是为什么你能看到下面这样的效果:
HTML5表单验证的例子

在你输入任何东西之前,框框里会有一个红色的标记,然后只要随便输入点什么,这个标记就会变成绿色的,这表示这些输入是有效的。

使用CSS可以把你自己的标记放在框框里面或者旁边,或者就像一些浏览器默认行为一样,简单的变一下背景色啊,边框颜色啊之类的。

这个’required’属性也适用于checkbox,可以看原文作者的另外一篇文章

2. 全新的Input元素的Type

普大喜奔,HTML5带来了更加有用的新INPUT元素类型。例如:email,url,number,tel,date,还有其他一些。

在iPhone和iPad里面,这些不同的类型将关联不同的键盘来让观众老爷更方便的输入,其他浏览器可能会结合这些属性来限制或者给用户输入提出建议。

INPUT type=”email”

看到没看到没,只要简单地把type变成email,结合required属性,浏览器就只会接受规定格式的email做为输入了。

Email Address: <input type="email" name="email" required placeholder="Enter a valid email address">

注意!在上面这个例子中,我们使用了另一个HTML5属性placeholder,这个属性可以在文本框中显示一段提示或者说明——这种效果,之前都是用一些翔一样的onfocus或者onblur的JS事件实现的。

上面的代码将产生下面的文本输入框:
(见原文)

再次重申,不同的浏览器可能用不同的方式实现。例如在Opera中,只要输入类似*@*这样的就可以了,而在Safari、Chrome或者Firefox中,用户则必须输入*@-.-这样的结构才行。显然,这例子是很有限的,但是它还是能阻止人们输入错误的值,比如电话号码呀,多个@或者空格呀之类的错误。

下面是Safari中的样子,当然是使用了自定义的CSS样式:
HTML5表单验证的例子

INPUT type=”url”

跟上面那个email相似,这个同样只能接受正确的URL形式,当然,这玩意儿现在看起来好像没啥变化,但是接下来是见证奇迹的一刻我们会使用pattern属性来提升他的交互。

Website: <input type="url" name="website" required>

现在看起来是这个屌样:
(见原文)

这种情况下,大多数浏览器允许一个或者多个字母带个冒号,这有神马用?但是这还是能阻止用户输入他们的email或者其他废话。

跟提到的一样,我们能用pattern属性来提升这一交互,这个属性接受一个JS正则表达式,所以会变成下面这样:

Website: <input type="url" name="website" required pattern="https?://.+">

这时候这个输入文本框将只接受开头是http://或者https://的文本。

如果你不懂啥是正则表达式,你应该赶紧优先搞懂它。对那些正则大牛,注意咯,^和$已经被隐含咯,那个表达式要匹配整个输入才行,正则表达式的修改模式则不被支持

如果有人当雷锋,贡献一个更加严格的匹配电子邮箱的正则表达式,欢迎去原文下面留言。

INPUT type=”number” 和 type=”range”

number类型和range类型也支持maxminstep属性,大多数情况step默认为1可以无视。

这里有个包含了上面俩的例子,前者表现为一个有上下选择箭的输入框,后者表现为一个滑块:

Age: <input type="number" size="6" name="age" min="18" max="99" value="21"><br>
Satisfaction: <input type="range" size="2" name="satisfaction" min="1" max="5" value="3">

和其他H5新成员一样,一小撮不求上进的浏览器压根不认识新的type或者某些属性,所以这时候这些输入域将会退化成一个单纯的文本输入框,所以加个size属性是个好主意的(因为size可以规定这些文本框的宽度,看起来比较好看)。

那个滑块看似不显示任何值,这一点有点奇葩,不过也好过一些类似的输入。对于number类型,这儿是有个bug存在的,如果你不设置max属性,那么如果你拼命按那个那个下箭头,不一会儿它就会显示一个很大很大的数值。。。

下面是它们俩在Safari下的样子:
HTML5表单验证的例子
还有在Opera里面的:
HTML5表单验证的例子

如果你觉得number元素中那两个箭头好丑不想要,那么你大可不用number只有普通的text然后设置它的pattern属性为"\d+",这个正则表达式匹配一个或多个数字。

INPUT type=”password”

我们有另一篇文章《validating passwords using HTML5》来专门讲这个,其中包括了用JS代码自定义浏览器发出的警告消息。

3. 其他一些Input元素的Type

其他的Input元素Type包括了一下各类:

  • color
  • date
  • datetime
  • datetime-local
  • month
  • search
  • tel
  • time
  • week

search类型在某些浏览器中将会改变自身的样式来符合浏览器或者操作系统本身的搜索域格式。

tel这个类型对于iphone这样的便携设备简直便利的爆炸,因为它将引出一个不同的输入键盘。不过它默认没有设置正则匹配,所以你得用pattern属性自强一个来限制输入。

color这个类型可以允许你从色盘或者类似的玩意儿里选择一个颜色,并以16进制表示它,但是现实是好像都不支持这个类型。

其他的类似date-time-相关的类型确实在Opera中有点作用,它会弹出一个日历或者其他东西来辅助输入。如果其他大部分浏览器都支持这些那就再好不过啦。不过现在大家只能用一些乱七八糟的JS控件来凑合了。

4. 用CSS来定制input元素的有效/无效输入样式

我们这儿使用的CSS有这么一丁点复杂,不过下面这个作为入门再合适不过啦:

input:required:invalid, input:focus:invalid {
/* 这儿可以设置这些元素的无效输入的样式 */
-moz-box-shadow: none;
}

这边这组样式可以用图标啊、改变文字颜色啊、标记边框啊之类的来标记那些输入无效的input。这个样式将在input元素是必须的且空的情况下,或者输入没有符合formatpattern的情况下出现。

这里出现的-moz-box-shadow样式是用来阻止Firefox 4 Beta中默认的加上红边框的行为。

对于那些既必须又有效的输入,可以用下面这个样式来设置:

input:required:valid {
/* 这儿可以设置这些元素的有效输入的样式 */
}

下面出现的内容中,尤其是前两个,提供了一些其他样式/脚本选项或者解决方案来适应老版本的一些浏览器。

5. 用图像和图像的一部分来作为样式的例子

跟前面讲的一样,一旦你对你的表单元素加入了H5的属性,它们就很容易用CSS对输入有效性定制样式。

<style type="text/css">

input:required:invalid, input:focus:invalid {
background-image: url(/images/invalid.png);
background-position: right top;
background-repeat: no-repeat;
}

input:required:valid {
background-image: url(/images/valid.png);
background-position: right top;
background-repeat: no-repeat;
}


</style>

这儿你可以看到上述的样式作用到一个input中的情况:
(见原文)

上面这个方案还是有点复杂的,因为它要载入两个图片,幸好,我们看到大部分支持HTML5有效性检测的浏览器都支持把图片用Data URI的形式来包装成一个“BASE64编码数据集”。

用一些手段例如SpriteBaker就能产生下面这样的样式:

<style type="text/css">

input:required:invalid, input:focus:invalid {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAeVJREFUeNqkU01oE1EQ/mazSTdRmqSxLVSJVKU9RYoHD8WfHr16kh5EFA8eSy6hXrwUPBSKZ6E9V1CU4tGf0DZWDEQrGkhprRDbCvlpavan3ezu+LLSUnADLZnHwHvzmJlvvpkhZkY7IqFNaTuAfPhhP/8Uo87SGSaDsP27hgYM/lUpy6lHdqsAtM+BPfvqKp3ufYKwcgmWCug6oKmrrG3PoaqngWjdd/922hOBs5C/jJA6x7AiUt8VYVUAVQXXShfIqCYRMZO8/N1N+B8H1sOUwivpSUSVCJ2MAjtVwBAIdv+AQkHQqbOgc+fBvorjyQENDcch16/BtkQdAlC4E6jrYHGgGU18Io3gmhzJuwub6/fQJYNi/YBpCifhbDaAPXFvCBVxXbvfbNGFeN8DkjogWAd8DljV3KRutcEAeHMN/HXZ4p9bhncJHCyhNx52R0Kv/XNuQvYBnM+CP7xddXL5KaJw0TMAF8qjnMvegeK/SLHubhpKDKIrJDlvXoMX3y9xcSMZyBQ+tpyk5hzsa2Ns7LGdfWdbL6fZvHn92d7dgROH/730YBLtiZmEdGPkFnhX4kxmjVe2xgPfCtrRd6GHRtEh9zsL8xVe+pwSzj+OtwvletZZ/wLeKD71L+ZeHHWZ/gowABkp7AwwnEjFAAAAAElFTkSuQmCC);
background-position: right top;
background-repeat: no-repeat;
-moz-box-shadow: none;
}

input:required:valid {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAepJREFUeNrEk79PFEEUx9/uDDd7v/AAQQnEQokmJCRGwc7/QeM/YGVxsZJQYI/EhCChICYmUJigNBSGzobQaI5SaYRw6imne0d2D/bYmZ3dGd+YQKEHYiyc5GUyb3Y+77vfeWNpreFfhvXfAWAAJtbKi7dff1rWK9vPHx3mThP2Iaipk5EzTg8Qmru38H7izmkFHAF4WH1R52654PR0Oamzj2dKxYt/Bbg1OPZuY3d9aU82VGem/5LtnJscLxWzfzRxaWNqWJP0XUadIbSzu5DuvUJpzq7sfYBKsP1GJeLB+PWpt8cCXm4+2+zLXx4guKiLXWA2Nc5ChOuacMEPv20FkT+dIawyenVi5VcAbcigWzXLeNiDRCdwId0LFm5IUMBIBgrp8wOEsFlfeCGm23/zoBZWn9a4C314A1nCoM1OAVccuGyCkPs/P+pIdVIOkG9pIh6YlyqCrwhRKD3GygK9PUBImIQQxRi4b2O+JcCLg8+e8NZiLVEygwCrWpYF0jQJziYU/ho2TUuCPTn8hHcQNuZy1/94sAMOzQHDeqaij7Cd8Dt8CatGhX3iWxgtFW/m29pnUjR7TSQcRCIAVW1FSr6KAVYdi+5Pj8yunviYHq7f72po3Y9dbi7CxzDO1+duzCXH9cEPAQYAhJELY/AqBtwAAAAASUVORK5CYII=);
background-position: right top;
background-repeat: no-repeat;
}


</style>

上面这个样式可以直接复制到你的css文件中,这不需要额外的图片资源了(减少了HTTP请求次数),并且如果你的样式文件是用gzip压缩过的话,那就更完美啦。只要2分钟,就能升级你的网站啦。

下面就是带有必须属性的input元素使用图片和Data URI在Safari中表现的样子:
HTML5表单验证的例子

同样的样式可以用在textarea中,但是没法用在checkbox或者select中。对于这些元素,你需要把有效性图标放在元素旁边或者改变元素本身的属性,例如边框、背景颜色等。

6. placeholder属性的回调函数

在IE8+、Firefox和Opera等浏览器中,下面这段JavaScript代码,如果放在页面文件的底部,应该可以支持input元素的placeholder属性:

<script type="text/javascript">

// ref: http://diveintohtml5.org/detect.html
function supports_input_placeholder()
{

var i = document.createElement('input');
return 'placeholder' in i;
}

if(!supports_input_placeholder()) {
var fields = document.getElementsByTagName('INPUT');
for(var i=0; i < fields.length; i++) {
if(fields[i].hasAttribute('placeholder')) {
fields[i].defaultValue = fields[i].getAttribute('placeholder');
fields[i].onfocus = function() { if(this.value == this.defaultValue) this.value = ''; }
fields[i].onblur = function() { if(this.value == '') this.value = this.defaultValue; }
}
}
}

</script>

7. 匹配input元素中不同数据类型的正则表达式

  • URL
<input type="url" pattern="https?://.+">
  • IPv4地址
<input type="text" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}">
  • 日期
<input type="text" pattern="\d{1,2}/\d{1,2}/\d{4}">
  • 价格
<input type="text" pattern="\d+(\.\d{2})?">
  • 经纬度
<input type="text" pattern="-?\d{1,3}\.\d+">

8. 参考文献

9. 关于表单验证的相关文章

10. 评论

(略)