javascript之表单验证 完美提升用户体验

引言

增加客户端的表单验证可以为用户提供更快的体验,但决不能忽视的是,客户端表单验证永远不应该取代服务器端的验证,而只能是辅助和增强。根据经验JavaScript验证表单基本分为以下几方面的内容,必填字段、特殊模式匹配等,还要注意错误的提示方式对一个表单的可用性有着极其重要的影响。

2建立表单

       首先建立一个具有代表性的表单来作为本文的实例。

请见附件表单验证V1(基本版)

//form.html

<html>

<head>

<title>Simple Form</title>

<link rel="stylesheet" href="form_style.css" type="text/css"/>

<script type="text/javascript" src="checkForm.js"></script>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head>

<body>

<form action="javascript:alert('提交成功');" method="POST">

    <fieldset>

         <legend>Personal Information</legend>

         <label for="name">Name</label>

         <input type="text" id="name" class="required text"/>

         *<br/>

         <label for="email">Email</label>

         <input type="text" id="email" class="required email text"/><br/>

         <label for="date">Date</label>

         <input type="text" id="date" class="required date text"/><br/>

         <label for="url">Website</label>

         <input type="text" id="url" class="url text" value="http://"/><br/>

         <label for="phone">Phone</label>

         <input type="text" id="phone" class="phone text"/><br/>

         <label for="age">Age</label>

         <input type="text" id="age"  class="required age text"/><br/>

         <input type="submit" value="Submit Form" class="submit"/>

    </fieldset>

</form>

</body>

</html>  

 

 

 

 

 

再建立一个css样式使其变的美观

//form_style.css

form {

      font-family: Arial;

      font-size: 14px;

      width: 300px;

}

fieldset {

      border: 1px solid #CCC;

      margin-bottom: 10px;

}

fieldset.login input {

      width: 125px;

}

legend {

      font-weight: bold;

      font-size: 1.1em;

}

label {

      display: block;

      width: 60px;

      text-align: right;

      float: left;

      padding-right: 10px;

      margin: 5px 0;

}

input {

      margin: 5px 0;

}

input.text {

      padding: 0 0 0 3px;

      width: 172px;

}

input.submit {

      margin: 15px 0 0 70px;

}

这样一个漂亮的表单就建立完成了。

提供客户端验证的主要优点在于,用户可以有一个校验他们输入的实时反馈,从而全面提高表单的输入体验。但这并不等于,实现了客户端的表单验证就可以忽视或者删除服务器端的验证。应该继续测试禁止JavaScript情况下的表单,确保不使用JavaScript的用户可继续拥有其他的可用性体验。

 

3必填字段

字段验证中最重要的可能就是必填字段(表示该条目用是户必须填写的)了。通常,这个必要条件可以简化为检查字段的值是否为空。但有时候,字段可能有一个默认的值,这就要求在注意这种可能性的同时要检查用户是否至少改变了字段默认值。这两种检查包含了表单字段的主要形式,包括<input type="text"><select><textarea>

尽管如此,当你试图检查用户是否修改了必填的复选框或者单选框时,还是可能产生问题。要巧妙地解决这个问题,你需要找出所有拥有相同name(这是字段元素关联的纽带)的字段,然后检查用户是否选择了其中的一个。

// checkForm.js

// 检查输入元素是否键入了信息的通用函数

function checkRequired( elem ) {

      if ( elem.type == "checkbox" || elem.type == "radio" )

           return getInputsByName( elem.name ).numChecked;

      else

           return elem.value.length > 0 && elem.value != elem.defaultValue;

}

// 找出指定name的所有input元素(对查找以及处理复选框或单选框十分有用)

function getInputsByName( name ) {

      // 匹配的input元素的数组

      var results = [];

      // 追踪被选中元素的数量

      results.numChecked = 0;

      // 找出文档中的所有input元素

      var input = document.getElementsByTagName("input");

      for ( var i = 0; i < input.length; i++ ) {

           // 找出所有指定name的字段

           if ( input[i].name == name ) {

               // 保存结果,稍后会返回

               results.push( input[i] );

               // 记录被选中字段的数量

               if ( input[i].checked )

                   results.numChecked++;

           }

      }

      // 返回匹配的字段集合

      return results;

}

// 等待文档完成加载

window.onload = function(){

    // 获得表单并监听提交事件

   document.getElementsByTagName("form")[0].onsubmit = function(){

        // 获取需检查的input元素

        var elem = document.getElementById("age");

        // 确保年龄的必填字段已经被选中

        if ( ! checkRequired( elem ) ) {

             // 否则显示错误并阻止表单提交

            alert( "Required field is empty – " );

            return false;

        }

        // 获取需检查的input元素

        var elem = document.getElementById("name");

        // 确保名字字段有文本输入

        if ( ! checkRequired( elem ) ) {

          // 否则显示错误并阻止表单提交

          alert( "Required field is empty – please provide your name." );

          return false;

        }

    };

};

4模式匹配

验证输入元素(尤其是文本字段)的第二大组件是模式匹配,它检验字段的内容是否符合要求。

使用以下技术的要点在于明白无误地定义字段的必须条件,否则,你可能会让用户产生困惑。比如日期格式会在特定文化的差异,甚至是不同规范的情况下而差别巨大。

以下是几种验证字段内容的技术,包括电子邮件地址、URL、电话号码和日期。

1)电子邮件

要求填写电子邮件地址无疑是Web表单中再普通不过的需求了,因为它是鉴定和交流的普遍手段。但要完全检查电子邮件地址的正确性(取决于它的规则)却非常复杂。你可以只概括性地检查所有可能的输入情况。

// 检查指定的input元素是否包含电子邮件地址

// 检查input元素内容是否符合emial地址要求的通用函数

function checkEmail( elem ) {

      // 确保输入的内容是正确的email地址

      return elem.value == '' ||

          /^[a-z0-9_+.-]+/@([a-z0-9-]+/.)+[a-z0-9]{2,4}$/i.test( elem.value );

}

// 获取需要检查的input元素

var elem = document.getElementById("email");

// 检查这个字段是否正确

if ( ! checkEmail( elem ) ) {

      alert( "Field is not an email address." );

}

2URL

表单(和其他的网络相关区域)的一个常见需求是要求用户输入网站的URL。与电子邮件地址一样,URL又是一个难以实现完全符合规范定义的例子,但只需实现规范中的一小部分即可达到目的。实际上,你只需检查基于httphttpsWeb地址(当然,即使有所不同也可方便修改)。此外,URL字段通常会有http://这样的字符串打头,在检查表单时必须考虑这种情形。

// 检查input元素是否包含URL的通用函数

function checkURL( elem ) {

    // 确保有文本的键入,而且不是默认的http://文本

    return elem.value == '' || !elem.value == 'http://' ||

        // 确保它是一个正确的URL

        /^https?:([a-z0-9-]+/.)+[a-z0-9]{2,4}.*$/.test( elem.value );

}

// 获取需要检查的inpu元素

var elem = document.getElementById("url");

// 检查它是否是一个正确的URL

if ( ! checkURL( elem ) ) {

    alert( "Field does not contain a URL." );

}

3)电话号码

电话号码,取决于你的所在地,它们有着不同的情形。为简化起见,将使用中国式的电话号码。当然,改变它们的规则以适应另一个国家或地区并不是十分困难只要改变相应的正则表达式就可以。

然后,还要试着处理电话号码字段中的一些特别之处。电话号码可以以不同的形式书写,所以你需要允许这些形式的输入(如0575-12345678(0575)1234567813336183980)。

这样一来你不仅需要验证数字本身,还要验证这种特殊的格式。你可以简单地逆向检查电话号码字段的值。

 

 

function checkPhone( elem ) {

      // 检查是否符合电话号码的要求

return elem.value == '' || /(^[0-9]{3,4}/-[0-9]{7,8}$)|(^[0-9]{7,8}$)|(^1[3|5|8]{1}[0-9]{9}$)/.test(elem.value);

// 0575-12345678(0575)12345678或现有存在的手机号码

}

// 获取需要检查的input元素

 

var elem = document.getElementById("phone");

// 检查这个字段是否包含正确的电话号码

if ( ! checkPhone( elem ) ) {

    alert( "Field does not contain a phone number." );

}

4)日期

最后要探索的是日期的验证。再次,你会看到美国式的日期书写格式(MM/DD/YYYY)。 就像电话号码或者其他由国别决定的不同字段,如果有必要,你可以方便修改验证的正则表达式以满足本土化需求。使用如代码清单8-7所示的具体验证函数,你就可以验证日期字段的内容了。

//检查input元素是否包含日期的通用函数

function checkDate( elem ) {

      // 确保输入了内容并检查是否符合MM/DD/YYYY的时间格式

      return !elem.value || /^/d{2}///d{2}///d{2,4}$/.test(elem.value);

}

// 获取需要检查的inpu元素

var elem = document.getElementById("date");

// 检查这个字段是否包含正确的日期

if ( ! checkDate( elem ) ) {

      alert( "Field is not a date." );

}

5 错误提示方式

在完成了各种字段的正则表达式检验的函数之后,就要加入错误提示和用户交互,其中最基本的错误提示方式是运用alert()方法弹出警告框,这种警告方式的有点在于编码方便但是缺乏了用户体验,附件:表单验证V1(基本版) 就是按照这种方式来实现的,如下图所示:

 

部分代码如下所示:

// 获取需检查的input元素

    var elem = document.getElementById("name");

     // 确保名字字段有文本输入

     if ( ! checkRequired( elem ) ) {

      // 否则显示错误并阻止表单提交

      alert( "Required field is empty – please provide your name." );

             return false;

        }

以上提示方式已经在正式场合很少出现了,只在测试时使用。

6 用户体验提升

在完成了上述版本之后,我发现会有某些问题影响到用户体验。

1、用户很厌烦表单输入错误点击提交后会弹出警告框很不友好;

2、修正了一个错误后又会依次检验下一个错误如果错误很多的话就要提交很多次另人生厌;

由于以上不足,应该在错误提示方式上做一定的修改,修改后的版本为附件:表单验证V2(提高版)

该版本的特点是在表单htmlcss上做了一定修改,在文本框边上加入了显示错误的字段(默认情况下是隐藏的,当出现错误是才会被显示)。如下图所示:

 

 

 

 

然后我们在Javascript中加入错误时触发显示错误字段的DOM操作。如下图:

 

 

这样的结果就是,当点击提交是所有存在的错误会显示在原有页面上而不是以警告框的方式显示,如下图所示:

 

这样用户就可以同时知道他存在的所有错误逐一修改后再提交,避免了重复提交的尴尬。

 

7 体验完美提升

通过了版本二的改进后,用户体验大大提升但还是没有达到挑剔用户满意的阶段。还存在以下问题:

1、用户并不知道他能输入什么格式的日期、电话等;

2、用户必须点击提交按钮才能知道错误在哪里,有时候会另用户感到不悦。

对于第一个问题我们可以在表单上做相应的注释或者填写一些默认信息来指明格式。如图:

 

对于第二个问题。我们需要一种即时的错误检验和反馈。应该在每当用户填写完相应字段后进行检验,有人会使用onkeypress这个消息映射,但是这个并不科学,因为用户每敲击一次键盘检验,用户输入第一个字符是往往是错误的,会造成用户还没有输入完之前都是错误的情况,这是用户不想看到的。所以应该使用onchange这个消息映射,他是在改变表单空间聚焦时发生检验,如用户填完用户名后点击下一个字段就会对用户名进行检验,具体见附件:表单验证V3(完美版)

 

实现这个效果必须为各个表单元素指定onchange映射,写法有很多,这里我使用了分离式脚本技术,这样的优点是使htmljavascript代码分离,便于管理,具体如下:

 

这样就能实现在用户填写表单的同时检验正确性,用户会非常乐意填写这样的表单。

 

8 总结

首先,作为实训的开发经理,本次读书报告主要是为了对实训中大量表单验证做准备,并且为团队中其他同学做一个javascript方面的培训。所以我分成三个版本来进行阐述是希望队友能够看懂并真正掌握这个在实训中要反复使用的技术。

同时,经过了这次重新编写表单验证,我把我原来的javascript编码风格改成了分离式脚本编写,这样更适合企业化开发和管理,是对我自己的一个提升。

 

 

 代码地址:表单验证demo.rar

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值