14.2.4 HTML5 约束验证API

优质
小牛编辑
116浏览
2023-12-01
为了在将表单提交到服务器之前验证数据,HTML5 新增了一些功能。有了这些功能,即便JavaScript被禁用或者由于种种原因未能加载,也可以确保基本的验证。换句话说,浏览器自己会根据标记中的规则执行验证,然后自己显示适当的错误消息(完全不用JavaScript 插手)。当然,这个功能只有在支持HTML5 这部分内容的浏览器中才有效,这些浏览器有Firefox 4+、Safari 5+、Chrome 和Opera 10+。 只有在某些情况下表单字段才能进行自动验证。具体来说,就是要在HTML 标记中为特定的字段指定一些约束,然后浏览器才会自动执行表单验证。

1. 必填字段

第一种情况是在表单字段中指定了required 属性,如下面的例子所示:
<input type="text" name="username" required>
任何标注有required 的字段,在提交表单时都不能空着。这个属性适用于<input>、<textarea>和<select>字段(Opera 11 及之前版本还不支持<select>的required 属性)。在JavaScript 中,通过对应的required 属性,可以检查某个表单字段是否为必填字段。
var isUsernameRequired = document.forms[0].elements["username"].required;
另外,使用下面这行代码可以测试浏览器是否支持required 属性。
var isRequiredSupported = "required" in document.createElement("input");
以上代码通过特性检测来确定新创建的<input>元素中是否存在required 属性。 对于空着的必填字段,不同浏览器有不同的处理方式。Firefox 4 和Opera 11 会阻止表单提交并在相应字段下方弹出帮助框,而Safari(5 之前)和Chrome(9 之前)则什么也不做,而且也不阻止表单提交。

2. 其他输入类型

HTML5 为<input>元素的type 属性又增加了几个值。这些新的类型不仅能反映数据类型的信息,而且还能提供一些默认的验证功能。其中,"email"和"url"是两个得到支持最多的类型,各浏览器也都为它们增加了定制的验证机制。例如:
<input type="email" name ="email">
<input type="url" name="homepage">
顾名思义,"email"类型要求输入的文本必须符合电子邮件地址的模式,而"url"类型要求输入的文本必须符合URL 的模式。不过,本节前面提到的浏览器在恰当地匹配模式方面都存在问题。最明显的是"-@-"会被当成一个有效的电子邮件地址。浏览器开发商还在解决这些问题。 要检测浏览器是否支持这些新类型,可以在JavaScript 创建一个<input>元素,然后将type 属性设置为"email"或"url",最后再检测这个属性的值。不支持它们的旧版本浏览器会自动将未知的值设置为"text",而支持的浏览器则会返回正确的值。例如:
var input = document.createElement("input");
input.type = "email";
var isEmailSupported = (input.type == "email");
要注意的是,如果不给<input>元素设置required 属性,那么空文本框也会验证通过。另一方面,设置特定的输入类型并不能阻止用户输入无效的值,只是应用某些默认的验证而已。

3. 数值范围

除了"email"和"url",HTML5 还定义了另外几个输入元素。这几个元素都要求填写某种基于数字的值:"number"、"range"、"datetime"、"datetime-local"、"date"、"month"、"week",还有"time"。浏览器对这几个类型的支持情况并不好,因此如果真想选用的话,要特别小心。目前,浏览器开发商主要关注更好的跨平台兼容性以及更多的逻辑功能。因此,本节介绍的内容某种程度上有些超前,不一定马上就能在实际开发中使用。

对所有这些数值类型的输入元素,可以指定min 属性(最小的可能值)、max 属性(最大的可能值)和step 属性(从min 到max 的两个刻度间的差值)。例如,想让用户只能输入0 到100 的值,而且这个值必须是5 的倍数,可以这样写代码:
<input type="number" min="0" max="100" step="5" name="count">

在不同的浏览器中,可能会也可能不会看到能够自动递增和递减的数值调节按钮(向上和向下按钮)。

以上这些属性在JavaScript 中都能通过对应的元素访问(或修改)。此外,还有两个方法:stepUp()和stepDown(),都接收一个可选的参数:要在当前值基础上加上或减去的数值。(默认是加或减1。)这两个方法还没有得到任何浏览器支持,但下面的例子演示了它们的用法。
input.stepUp(); //加1
input.stepUp(5); //加5
input.stepDown(); //减1
input.stepDown(10); //减10

4. 输入模式

HTML5 为文本字段新增了pattern 属性。这个属性的值是一个正则表达式,用于匹配文本框中的值。例如,如果只想允许在文本字段中输入数值,可以像下面的代码一样应用约束:
<input type="text" pattern="\d+" name="count">
注意,模式的开头和末尾不用加^和$符号(假定已经有了)。这两个符号表示输入的值必须从头到尾都与模式匹配。 与其他输入类型相似,指定pattern 也不能阻止用户输入无效的文本。这个模式应用给值,浏览器来判断值是有效,还是无效。在JavaScript 中可以通过pattern 属性访问模式。
var pattern = document.forms[0].elements["count"].pattern;
使用以下代码可以检测浏览器是否支持pattern 属性。
var isPatternSupported = "pattern" in document.createElement("input");

5. 检测有效性

使用checkValidity()方法可以检测表单中的某个字段是否有效。所有表单字段都有个方法,如果字段的值有效,这个方法返回true,否则返回false。字段的值是否有效的判断依据是本节前面介绍过的那些约束。换句话说,必填字段中如果没有值就是无效的,而字段中的值与pattern 属性不匹配也是无效的。例如:
if (document.forms[0].elements[0].checkValidity()) {
//字段有效,继续
} else {
//字段无效
}
要检测整个表单是否有效,可以在表单自身调用checkValidity()方法。如果所有表单字段都有效,这个方法返回true;即使有一个字段无效,这个方法也会返回false。
if (document.forms[0].checkValidity()) {
//表单有效,继续
} else {
//表单无效
}
与checkValidity()方法简单地告诉你字段是否有效相比,validity 属性则会告诉你为什么字段有效或无效。这个对象中包含一系列属性,每个属性会返回一个布尔值。
  • customError :如果设置了setCustomValidity(),则为true,否则返回false。
  • patternMismatch:如果值与指定的pattern 属性不匹配,返回true。
  • rangeOverflow:如果值比max 值大,返回true。
  • rangeUnderflow:如果值比min 值小,返回true。
  • stepMisMatch:如果min 和max 之间的步长值不合理,返回true。
  • tooLong:如果值的长度超过了maxlength 属性指定的长度,返回true。有的浏览器(如Firefox 4)会自动约束字符数量,因此这个值可能永远都返回false。
  • typeMismatch:如果值不是"mail"或"url"要求的格式,返回true。
  • valid:如果这里的其他属性都是false,返回true。checkValidity()也要求相同的值。
  • valueMissing:如果标注为required 的字段中没有值,返回true。
因此,要想得到更具体的信息,就应该使用validity 属性来检测表单的有效性。下面是一个例子。
if (input.validity && !input.validity.valid) {
if (input.validity.valueMissing) {alert("Please specify a value.")
} else if (input.validity.typeMismatch) {alert("Please enter an email address.");
} else {alert("Value is invalid.");
}
}

6. 禁用验证

通过设置novalidate 属性,可以告诉表单不进行验证。
<form method="post" action="signup.php" novalidate>
    <!--这里插入表单元素-->
</form>
在JavaScript 中使用noValidate 属性可以取得或设置这个值,如果这个属性存在,值为true,如果不存在,值为false。
document.forms[0].noValidate = true; //禁用验证
如果一个表单中有多个提交按钮,为了指定点击某个提交按钮不必验证表单,可以在相应的按钮上添加formnovalidate 属性。
<form method="post" action="foo.php">
<!--这里插入表单元素-->
<input type="submit" value="Regular Submit">
<input type="submit" formnovalidate name="btnNoValidate"
value="Non-validating Submit">
</form>
在这个例子中,点击第一个提交按钮会像往常一样验证表单,而点击第二个按钮则会不经过验证而提交表单。使用JavaScript 也可以设置这个属性。
//禁用验证
document.forms[0].elements["btnNoValidate"].formNoValidate = true;