HTML5使用'pattern'属性进行表单校验(译文)

下面这份指南将会探索HTML5的‘pattern’属性,这个属性可以帮助我们定制我们自己的表单验证。

验证(Validation)

表单校验在网站的安全性方面启到的作用与网站的实用性是同等重要的。表单校验工作原理是在提交表单之前,评估输入的内容格式是否正确。例如,如果我们有一个邮箱地址框,那填入的信息必须是有效的邮箱地址;它应该是以字母或数字开头,随后是‘@’字符,并以一个域名地址结尾。

HTML5自带的一些新的文本类型极其预先定义好的一些校验规则,例如email、url及tel等,让表单校验变的更加简单。当输入的值与期望输入的格式不匹配时,输入框会抛出一个错误信息来阻止提交。
email
预估每一种可能的输入是不切实际的,比如,如果我们需要一个用户名、邮编、或者其他任何格式的特殊输入,我们该怎么办,怎么去校验这些输入呢?这就到了我们今天的主题–’pattern’属性。

使用’Pattern’属性

‘pattern’属性只对’input’元素有效。我们可以使用正则表达式定义我们自己的校验规则。同样的,如果输入值不满足条件,输入框会抛出一个异常。

例如,加入我们的表格中有一个用户名输入框,因为我们没有针对用户名的校验标准,因此,我们需要使用正则表达式来校验我们的输入内容。

1
2
3
<form action="somefile.php">
<input type="text" name="username" placeholder="Username">
</form>

下面我们使用’pattern’属性来定义一个规则。假使,我们指定用户名只能由小写字母组成,不允许输入大写字母、数组或者其他特殊字符。另外,用户名的长度不该超过15个字符。用正则来表示的话,规则是’[a-z]{1,15}’。

在我们的用户名输入框中的pattern属性中添加上述值:

1
2
3
<form action="somefile.php">
<input type="text" name="username" placeholder="Username" pattern="[a-z]{1,15}">
</form>

好了,现在它只支持输入小写字母,提交任何其他值都会抛出一个错误信息。
username
就像上面你看到的那样,错误信息是“请按规则输入(Please match the requested format)”。这表示我们的校验生效了,但是,这样的错误信息不利于我们理解我们实际上希望输入怎样的格式。这样的用户体验很失败。

定制校验信息(Customizing the Validation Message)

幸运的是,我们有很多种方式去可以定制更加有用的信息。最直观的方式就是在input元素的’title’属性上添加。

1
2
3
4
5
6
7
8
<form action="somefile.php">
<input
type="text"
name="username"
placeholder="Username"
pattern="[a-z]{1,15}"
title="Username should only contain lowercase letters. e.g. john">
</form>

现在,标题中包含了默认的提示信息:
username1
然而,这个信息提示框还是前后不一致。如果我们拿它与一个邮箱格式的输入框相比,实际的说明应该更突出一点。

第二种方案可以帮助我们解决这个问题。

替换默认的校验信息(Replacing the Default Validation Message)

让我们用一个完全自定义的信息来替换默认的“请按规则输入(Please match the requested format)”。我们需要用到一点JavaScript。

开始之前,为了更好的选中input元素,我们先给它加上id。

1
2
3
4
5
6
7
8
<form action="somefile.php">
<input
type="text"
name="username"
placeholder="Username"
pattern="[a-z]{1,15}"
id="username">
</form>

现在,我们可以用JavaScript选中元素,并赋值给一个变量。(可以直接使用”script”标签或者引入一个额外的JavaScript文件)

1
var input = document.getElementById('username');

然后,当输入框触发校验状态的时候,我们指定特定的信息。

1
2
3
input.oninvalid = function(event) {
event.target.setCustomValidity('Username should only contain lowercase letters. e.g. john');
}

“oninvalid”事件继承自”event”对象,其包涵有一系列属性,包括”target”属性(校验的元素)及带有错误信息的”validationMessage”属性。
在上面的例子中,我们使用”setCustomValidity()”方法替换了提示信息。

现在我们应该可以发现默认的提示信息被无缝替换了。
username3

样式(Styling)

为了补充新的输入类型及设置一个自定义的验证消息,CSS3规范带来了几个有用的伪类,’:valid’及’:invalid’。这就能够让我们根据不同的输入校验状态应用相应的样式,例如:

1
2
3
4
5
6
7
input:invalid {
border-color: red;
}
input,
input:valid {
border-color: #ccc;
}

当使用这些伪类时,有几点需要记住的是:

  • 首先,”:valid”是默认样式,即使输入值为空。因此,正如上面你看到那样,我们设置”border-color”为”#ccc”,则输入框元素默认的颜色也是这个。空值永远被认为是有效输入,除非我们已经加了“必填”(required)属性。那样的话,输入校验无效,边框将变成给定的红色。
  • 有效和无效样式将在用户输入时立马生效,即使值为空。即时样式改变可能会造成用户的恐慌。

弹出框样式一致性(A Word on Styling the Popup Message)

表单校验作为一个HTM5的特性已经变成了一种规范,然而,错误信息提示框如何呈现却完全取决于浏览器厂商。
如果在不同的浏览器上呈现不一样的效果,这对你界面的一致性是没有帮助的。
html5-validation-different-browsers

谷歌浏览器在几年前阻止用户去自定义默认的弹框。如果你想做啥改变的话,唯一可供选择的方式是使用JavaScript覆盖弹框信息,下面我们来看看应该怎么做。

进阶(Going More Advanced)

我们先创建一个当我们的输入值有效的时候才呈现的自定义弹框。在一开始,我们需要选中一些必要的元素,包括”input”及”form”元素:

1
2
var input = document.getElementById('username');
var form = document.getElementById('form');

然后,新建一个包含我们信息的新元素:

1
2
3
4
var elem = document.createElement('div');
elem.id = 'notify';
elem.style.display = 'none';
form.appendChild(elem);

上面我们创建了一个新的div元素,设置其id为”notify”,设置其”display”样式为”none”。最后,将其插入到”form”元素中。

使用事件(Working with Events)

我们需要处理两个事件。首先,当输入的值不合法的时候,需要触发”invalid”事件。下面我们添加”invalid”事件:

1
2
3
4
5
6
7
8
9
10
input.addEventListener('invalid', function(event){
event.preventDefault();
if ( ! event.target.validity.valid ) {
elem.textContent = 'Username should only contain lowercase letters e.g. john';
elem.className = 'error';
elem.style.display = 'block';
input.className = 'invalid animated shake';
}
});

在这里,利用”event.preventDefault();”,我们可以阻止默认的行为,这样浏览器就不会显示默认的弹框。
相反,我们显示新建的div元素。我们在内容区域里添加文本信息,添加新的样式”error”,并且通过设置”display”属性为”block”来显示信息。

同样的,我们给输入框添加一个”invalid”样式,让它边框为红色。我们也需要在样式表中设置其样式:

1
2
3
input.invalid {
border-color: #DD2C00;
}

另外,你也可以加一些抖动样式通过”Animate.css”,这可以加上一些抖动的动画。

第二个事件是”input”事件,它将在输入值改变的时候触发。我们可以使用这个事件将输入值恢复到合法输入的状态,也可以隐藏弹出框,如下:

1
2
3
4
5
6
input.addEventListener('input', function(event){
if ( 'block' === elem.style.display ) {
input.className = '';
elem.style.display = 'none';
}
});

如上文,我们可以通过移除input元素的样式来隐藏弹出框。
现在我们可以完全定制自己的弹出校验框了,试试输入任何一些非法的值。

最后几点(Final Thoughts)

在标准的输入类型中加上pattern属性可以给表单带来一些额外的校验形式,但是请注意,你也应该执行一些服务器端的校验。

神奇的是,即使当用户禁止了浏览器端的JavaScript,最新版的浏览器也会显示校验提示框并阻止表单提交。
然而,对于Safari浏览器来说,在用户输入时,不支持pattern属性。不过使用”Webshim Lib”也可以启到类似的效果。

最后,希望你能喜欢本教程,并且将其作为一个针对HTML5表单校验的简单参考指南。
(本文译自:HTML5 Form Validation With the “pattern” Attribute)



money☜☜☜ wechat 『『『 reward 点击扫码打赏 ~~~ ^_^ 』』』alipay ☞☞☞ money