在填写表单时,我们经常见到指定用户必须填写某些字段(比如注册邮箱等),然后才能提交表单。可以使用JavaScript检查某些或所有字段是否已经填写了。在下面的例子中,我们使用HTML、CSS和JavaScript通过红色的边框和×××的内部颜色突出显示未填写的字段。检查在表单提交时进行。

    检查方法的基本原理如下:HTML中的class属性表示我们希望Javascript执行哪种检查。如果检查失败,就在class属性列表中添加invalid。

这样做会出现两种现象:(1)表单提交失败;(2)脚本中的CSS改变这个字段在页面上的外观

HTML&CSS代码:

  1. <style type="text/css"> 
  2. body { 
  3.     color:#000; 
  4.     background-color:#fff; 
  5.     } 
  6. input.invalid { 
  7.     background-color:#FF9; 
  8.     border:2px red inset; 
  9.     } 
  10. label.invalid { 
  11.     color:#F00; 
  12.     font-weight:bold; 
  13.     } 
  14. </style> 
  15. <body> 
  16. <form action="#"> 
  17.     <p><label for="userName">Your name:<input type="text" size="30" id="userName" class="reqd"/></label></p> 
  18.     <p><label for="passwd1">Choose a password:<input type="password" id="passwd1" class="reqd"/></label></p> 
  19.     <p><label for="passwd2">Verify password:<input type="password" id="passwd2" class="reqd passwd1"/></label></p> 
  20.     <p><input type="submit" value="Submit"/>&nbsp;<input type="reset"/></p> 
  21. </form> 
  22. </body> 

JavaScript代码及注释:

  1. window.onload = initForms
  2.  
  3. function initForms() { 
  4.     for (var i=0; i< document.forms.length; i++) { 
  5.         document.forms[i].onsubmit = validForm;

    //为每个表单的onsubmit添加一个事件处理程序:调用validForm。当onsubmit处理程序返回false值时,表单就不会被传递回服务器。

    //但是,即使出现了false,我们仍然继续循环遍历所有标签

  6.     } 
  7.  
  8. function validForm() { 
  9.     var allGood = true
  10.     console.log("start allGood=",allGood); 
  11.     var allInputs = document.getElementsByTagName("input"); //返回一个包含页面上所有<input>标签
  12. 的数组,然后就可以遍历allInputs数组来寻找有问题的内容了
  13.  
  14.     for (var i=0; i<allInputs.length; i++) { 
  15.         if (!validTag(allInputs[i])) { 
  16.             allGood = false
  17.         }

    //传递给validTag()函数的是allInputs[i],也就是当前正处理的对象。如果任何标签导致validTag()返回false,

  18. //就将allGood设置为false。

  19.     } 
  20.   
  21.     return allGood;//只有在返回true值时,服务器才会收到表单
  22.  
  23.     function validTag(thisInput) { //thisInput为当前的〈input〉标签对象
  24. //检查每个〈input〉标签,了解是否有什么东西阻止表单提交这个页面
  25.         var outClass = ""
  26.         var allClasses = thisInput.className.split(" ");
            //检查每个class属性(class可以设置多个属性)
    
  27.        for (var j=0; j<allClasses.length; j++) { //遍历每个标签的class属性
  28.             outClass += validBasedOnClass(allClasses[j]) + " ";
  29.         } 
  30.         thisInput.className = outClass;

    //结束allClasses循环时,我们获得outClass的内容替换当前标签的class属性

  31.         if (outClass.indexOf("invalid") > -1) { //检查新属性
  32.             thisInput.focus(); 
  33.             if (thisInput.nodeName == "INPUT") { 
  34.                 thisInput.select(); 
  35.             }//当前的标签若是<input>标签,就选择它的值,让用户能够轻松地修改它 
  36.             return false; 
  37.         }

    //在新的class属性中如果包含invalid,就说明有的表单没被填写,就执行大括号内的的操作:获得焦点等。

    然后返回false

  38.         return true;//如果新的class属性不包含invalid,则返回true 
  39.  
  40.         function validBasedOnClass(thisClass) {//对标签的(class)属性进行操作
  41.             console.log("当前的class为:",thisClass); 
  42.             var classBack = ""; //要返回的新属性
  43.             switch(thisClass) {//检查当前的一个class属性
  44.                 case "": 
  45.                 case "invalid": 
  46.                     if(thisClass != "" && crossCheck(thisInput,"passwd1")){classBack = "reqd";} 
  47.                     console.log("this invalid,thisClass=",thisClass); 
  48.                     break; 
  49. //当class属性为invalid(且不为空不是第一种情况),那么它就是验证密码表单项,那么就根据passwd1
  50. //字段对其进行验证,验证成功就去掉invalid属性(去掉红框背景色等)
  51.                 case "reqd": 
  52.                     if (allGood && thisInput.value == "") { 
  53.                         classBack = "invalid "
  54.                     } 
  55.                     classBack += thisClass; 
  56.                     break; 

    //如果正在处理的属性是reqd(必须填写),allGood是true(即此处之前的表单项都没有问题,此处是第一处导致不能提交的。见下图)

    //而且当前标签的当前值为空,那么将classBack设置为invalid,说明有问题,我们希望告知用户。在此之后,无论是否有问题,

    //我们都将当前的class属性追加到clasBack中,使它不会丢失。(比如passwd2空的class="reqd passwd1",返回值classBack=invalidpasswd1 或 reqdpasswd1)

  57.                 default: 
  58.                     if(allGood && !crossCheck(thisInput,thisClass)){//thisInput为当前的标签,thisClass为当前的class属性(passwd1) 
  59.                         classBack = "invalid "; //注意invalid后的空格一定不能丢,如果丢了
  60. //若reqd属性后还有别的属性会使两个属性字符串连写,两个class属性都不会有效。

    //比如Verify password:空的class=“reqd passwd1”,没有空格新属性会变成invalidpasswd1而不是invalid passwd1。

  61.                     } 
  62.                     classBack += thisClass; 
  63.             } 
  64.             return classBack; 
  65.         } 
  66.         function crossCheck(inTag,otherFieldID){ //根据其他字段对字段进行验证
  67.             if(!document.getElementById(otherFieldID)){ 
  68.                 return false; //另一个字段不存在,就无法进行检查
  69.                 } 
  70.             //alert(inTag.value); 
  71.             return (inTag.value == document.getElementById(otherFieldID).value); 
  72. //如果两个字段都存在,比较两个字段得值,如果相同,就返回true
  73.             }//end of crossCheck
  74.     } 

如下图,有两个必须填写的空都没有填写,只用颜色标出第一个:

提示密码字段为空:

验证密码错误:

验证通过,表单提交(通过地址栏最后的#号得知)

注:

HTML <label>标签

    为input元素定义标注(标记)

    label元素不会向用户呈现任何特殊效果。不过,它为鼠标用户改进了可用性。如果您在label元素内点击文本,就会触发此控件。就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。

 

    <lable>标签的for属性应当与相关元素的id属性相同。

  1. <form> 
  2.   <label for="male">Male</label> 
  3.   <input type="radio" name="sex" id="male" /> 
  4.   <br /> 
  5.   <label for="female">Female</label> 
  6.   <input type="radio" name="sex" id="female" /> 
  7. </form>     //也可以将input标签包含在label标签内

能实现的效果就是,点击文本(Male、Female)相应的单选按钮就会被选中。