3.5 表单验证
表单验证是一套系统,它为终端用户检测无效的数据并标记这些错误,使用表单验证有两个好处:既避免了信息无法更新或出现新错误,又减轻了服务器端的压力。表单验证是一种用户体验的优化,让Web应用更快地抛出错误,但它仍不能取代服务器端的验证。由于前端验证是可以绕过的,因此,重要数据还要依赖于服务器端的验证。
3.5.1 自动验证
自动验证是HTML 5表单默认的验证方式,它会在表单提交时执行自动验证,如果验证不通过,将无法提交表单。
HTML 5中通过许多属性都能完成表单的自动验证,如下所示为与自动验证有关的属性说明。
1.required属性
该属性的主要目的是确保表单元素中的值已填写。在提交时,如果元素中内容为空白则不允许提交,同时在浏览器中显示信息提示文字,提示用户该元素中必须输入内容。
2.pattern属性
该属性根据设置的正则表达式的格式验证输入的内容是否有效,如果无效则不允许进行提交。
3.max属性和min属性
max属性和min属性主要限制数字类型输入范围的最大值和最小值,不在范围内的不允许进行提交。
4.step属性
step属性限制元素的值每次增加或者减少的基数,如果不是基数倍数时不允许提交。例如,当想让用户输入的值在0~100之间,而且必须是5的倍数时,可以将step属性的值指定为5。
3.5.2 显式验证
可以使用自动验证方式对用户输入的内容进行验证,但是,自动验证并不能够完全满足用户的要求,这时,可以通过调用checkValidity()方法对表单内所有元素或者单个元素进行有效性验证。
当想要覆盖浏览器的默认验证和反馈过程时可以使用checkValidity()方法,该方法根据验证检查成功与否,返回true或false,同时也会通知浏览器运行其检查。HTML 5中的form元素、input元素、select元素和textarea元素都具有该方法。
【练习23】
本次练习完成一个简单的留言验证,在页面中添加用于留言的用户名、邮箱地址和留言内容,然后在单击按钮时判断输入的内容是否合法。
(1)添加新的页面并且进行设计,在页面中添加表示留言信息的表单,然后向表单中添加元素,再根据需要为每个元素添加属性。代码如下。
<form action="" method="post" name="formgb" id="formgb"> <p>您的大名:<input type="text" size="50" style="width:235px" class="input2" name="name" autofocus="true" required="true"></p> <p>您的邮箱:<input type="email" size="50" class="input2" name="email"></p> <p>您的留言内容:<textarea cols="40" rows="3" id="ccontent" name="content" class="input2" required="true"></textarea></p> <p><input type="button" value="立即发表" class="button" onClick="CheckInput()"></p> </form>
(2)用户单击【立即发表】按钮时触发其Click事件调用CheckInput()脚本函数。该函数的代码如下。
function CheckInput(){ var forms = document.forms["formgb"]; //获取表单元素 var name = forms.name; //获取用户输入的用户名 var mail = forms.email; //获取用户输入的邮箱 var content = forms.content; //获取用户输入的内容 if(!name.checkValidity()){ //判断用户名是否合法,如果不合法 alert("发言时您的大名怎么能为空呢!"); name.focus(); return false; } if(!mail.checkValidity()){ //判断邮箱是否合法,如果不合法 alert("为了方便对您的留言进行调查,请输入一个有效的邮箱地址!"); mail.focus(); return false; } if(!content.checkValidity()){ //判断发言内容是否合法,如果不合法 alert("您要发言的内容不能为空!"); content.focus(); return false; } }
(3)运行网页查看运行效果,向页面的文本框中输入内容后单击【立即发表】按钮测试效果,如图3-35所示为验证邮箱时的效果。
图3-35 使用checkValidity()方法进行验证
除了checkValidity()方法外,form和input元素还存在一个validity属性,该属性返回一个ValidityState对象,该对象的最常用属性是valid,valid表示表单内所有元素的内容是否有效。
【练习24】
例如,重新更改练习23中的代码,通过input元素的validity属性所返回ValidityState对象的valid属性进行判断。JavaScript中的代码如下。
function CheckInput(){ var forms = document.forms["formgb"]; //获取表单元素 var name = forms.name; //获取用户输入的用户名 var mail = forms.email; //获取用户输入的邮箱 var content = forms.content; //获取用户输入的内容 if(!name.validity.valid){ //验证用户名是否合法,如果不合法 alert("发言时您的大名怎么能为空呢!"); name.focus(); return false; } }
3.5.3 自定义验证
HTML 5中的许多input元素都带有对输入内容进行有效性检查的功能,如果有效性检查不通过,那么浏览器会针对元素提供错误信息。但是,有时候开发人员并不想使用这些默认的错误信息,而想自己定义错误信息,或者想给某个文本框增加一种错误信息等,这时可以使用setCustomValidity()方法。
setCustomValidity()方法与checkValidity()方法一样,通常都会结合JavaScript脚本一起使用,该方法适用于HTML 5中的所有input元素。
【练习25】
本次练习继续更改上面内容的代码,实现的具体步骤如下。
(1)更改form表单中的代码,为输入内容的每个元素都添加id属性,name属性可以去掉,也可以保存,最后更改按钮的类型为submit。部分代码如下。
<textarea cols="40" rows="3" id="content" name="content" class="input2"></textarea> <input type="submit" value="立即发表" class="submit" onClick="CheckInput()">
(2)重新更改JavaScript中的CheckInput()函数,在该函数代码中判断用户名、邮箱和内容不能为空,邮箱必须合法,并且输入的内容不能少于10个字。部分代码如下。
function CheckInput(){ var username = document.getElementById("name"); var email = document.getElementById("email"); var content = document.getElementById("content"); if(username.value=="" || username.value==null){ username.setCustomValidity("请输入人名,发言人名称不能为空!"); username.focus(); return false; } }
(3)运行页面输入内容进行测试,查看提示效果。由于浏览器不同,可能提示的样式也会有所不同,如图3-36和图3-37所示分别为Maxthon浏览器和Opera浏览器中的效果。
图3-36 Maxthon浏览器效果
图3-37 Opera浏览器效果
3.5.4 验证事件
除了与验证有关的属性和方法外,HTML 5还提供了对表单的事件验证。表单元素为通过验证时触发,无论是提交表单还是直接调用checkValidity()方法,只要有表单元素没有通过验证,就会触发invalid事件。通过这个事件,可以处理和检查验证失败有关的信息,并向用户反馈。
【练习26】
invalid事件本身不处理任何事情,可以通过监听该事件,自定义事件处理,下面通过一个简单的练习演示invalid事件的使用方法。
(1)添加一个新的页面,在页面的form表单中添加用于输入的email类型的input元素和执行验证操作的submit类型的input元素。代码如下。
<form name="formgb" id="formgb"> <input type="email" size="50" id="email" placeholder="电子邮箱" required> <input type="submit" value="立即发表" class="submit"> </form>
(2)继续向表单中添加一个span元素,该元素显示错误提示信息。代码如下。
<span id="msginfo" style="color:red; font-size:16px;">f</span>
(3)在JavaScript脚本中添加页面初始化的load事件,该事件调用loadDemo()函数。向loadDemo()函数中添加注册表单的invalid事件,并且在该事件中调用invalidHandler()函数进行验证,然后通过for语句遍历表单中的内容,为每一项内容添加change事件,该事件调用checkvalue()函数。代码如下。
function invalidHandler(evt) { //定义表单验证方法 checkvalue(evt); } function loadDemo() { var myform = document.getElementById("formgb"); myform.addEventListener("invalid", invalidHandler, true); //注册表//单的oninvalid事件 for(var i=0;i< myform.elements.length-1;i++){ //注册表单元素的onchange事件,优化用户体验 myform.elements[i].addEventListener("change",checkvalue,false); } } window.addEventListener("load", loadDemo, false); //在页面初始化事件时注册的自定义事件
(4)checkvalue()函数主要调用当前项的checkValidity()方法进行验证,然后进行判断,如果验证不通过则为获取的span元素的innerHTML属性进行赋值。该函数代码如下。
var checkvalue = function(e){ var msg = document.getElementById("msginfo"); //获取span元素 var el = e.target; var isvalid = el.checkValidity(); //验证内容 if(!isvalid){ msg.innerHTML = "邮箱编号为空或者格式错误,请重新输入。"; } e.stopPropagation(); e.preventDefault(); //屏蔽浏览器后续错误 }
(5)运行页面,然后向页面中输入内容后单击按钮进行测试,具体效果图不再显示。
通过使用invalid事件使表单开发更加灵活,一般情况下,在invalid事件处理完成后,还是会触发浏览器默认的错误提示。必要时可以屏蔽浏览器后续的错误提示,可以使用事件的preventDefault()方法,阻止浏览器的默认行为,并自行处理错误提示信息。
3.5.5 取消验证
一个非常大的表单需要分为两部分,或者更多部分,在第二部分中有个文本框的内容是一定要填的,如果填写每一部分内容则会消耗很多的时间。或者填写完第一部分内容后,还要过一段时间填写第二部分的内容,这时应该允许用户先提交保存第一部分的内容,同时临时取消第二部分的内容表单验证。
取消表单验证的常用方法有两种,第一种是利用form表单元素的novalidate属性,它可以关闭整个表单验证,这样可以使form内所有表单控件不进行验证。如果表单的第二部分需要验证的内容过多,但是又想要提交表单的第一部分时,可以使用这种方法。
另外一种方法是利用input元素或者submit元素的formnovalidate属性,这样可以控制单个表单控件的验证。利用input元素的formnovalidate属性可以让表单验证对单个input元素失效,例如,当表单的第二部分需要验证的内容数量很少时,可以使用这种方法。为submit按钮使用formnovalidate属性,用户单击按钮时,相当于利用form元素的novalidate属性,整个表单都失效了。