天天看點

打造可複用可擴充javascript驗證表單腳本

如果需要從使用者那裡收集資訊,就需要使用表單。

表單包含大多數常見的圖形界面元素,例如文本框,單選按鈕,複選框,下拉菜單等等。

填寫完表單,點選Submit按鈕将表單發送給web伺服器,盡管可以通過伺服器CGI程式完成驗證,但在用戶端用javascript驗證要快得多,而且使用者操作的效率也高。

這篇部落格,主要是把我寫的一個用于驗證表單的可複用,可擴充的javascript腳本(版本1.0)分享給大家.

​先來看看實作效果:​

​1、初始表單​

2、送出,

如果Email為空,則:

​3、如果Email不符合規範,則:​

​4、如果沒有選擇下拉框内容,則:​

5、如果沒有選擇單選按鈕中的一個,則:

6、根據已選字段,自動選擇其他字段:選擇NormalUser會自動選擇2G

驗證兩個至少選一個:如果沒有輸入位址,也沒有選擇位址,則:

​7、驗證郵編:如果輸入錯誤的郵編則:​

​8、驗證檔案:如果輸入錯誤的Image格式,則:​

javascript腳本(ValidForm1.js):

/ JavaScript Document

window.onload=initForms;

function initForms(){
  for (var i=0;i<document.forms.length;i++){
    //周遊所有表單,執行驗證
    document.forms[i].onsubmit=function(){return validForm();}
  };
  //為複選框NormalUser注冊事件
  document.getElementById("NormalUser").onclick=spaceSet;
};


function validForm(){
  var allGood=true;
  //獲得所有标簽
  var allTags=document.getElementsByTagName("*");

  for (var i=0;i<allTags.length;i++){
    //檢驗所有标簽
    if(!validTag(allTags[i])){
      allGood=false;
      };
    };
      return allGood;

    //檢驗标簽是否有效
      function validTag(thisTag){
      var outClass="";
      //獲得該标簽的class屬性
      var allClasses=thisTag.className.split(" ");
      for (var j=0;j<allClasses.length;j++){
        //驗證該标簽,通過改變class辨別無效标簽
        outClass += validBasedOnClass(allClasses[j])+" ";
      };

      thisTag.className=outClass;

      if(outClass.indexOf("invalid")>-1){
        //辨別出無效的輸入值前的标簽
        invalidLabel(thisTag.parentNode);
        //無效輸入标簽獲得焦點
        thisTag.focus();
        //如果是輸入标簽,則選中其中的文本
        if(thisTag.nodeName=="INPUT"){
          thisTag.select();
        };
        return false;
      };
        return true;


      //辨別無效的字段,添加類名invalid
      function validBasedOnClass(thisClass){
        var classBack="";
        //驗證,在這裡可以擴充驗證
        switch(thisClass){
          case "":
          case "invalid":
            break;
          case "reqd":
              //判斷空
            if (allGood && thisTag.value=="")
            //invalid後有空格
            {classBack="invalid ";};
            classBack += thisClass;
            break;
            case "radio":
              //檢查是否已選單選框
            if(allGood && !radioPicked(thisTag.name)){classBack="invalid ";};
            classBack += thisClass;
            break;
          case "isNum":
            //檢查是否是數字
            if(allGood && !isNum(thisTag.value)){classBack="invalid ";};
            classBack += thisClass;
            break;
          case "isEmail":
            //檢查是否是Email
            if(allGood && !isEmail(thisTag.value)){classBack="invalid ";};
            classBack += thisClass;
            break;
          case "isImage":
            //檢查是否是圖檔,可以演化為檢查檔案名
            if(allGood && !isImg(thisTag.value)){classBack="invalid ";};
            classBack += thisClass;
            break;
          case "isPostcode":
              //檢查郵政編碼
              if(allGood && !isPostcode(thisTag.value)){classBack="invalid ";};
            classBack += thisClass;
            break;
          case "isAddress":
            classBack += thisClass;
            break;
          default:
             //invalid後有空格
             //檢查是否至少已經設定了兩個字段之一
             if(allGood && !crossCheck(thisTag,thisClass)){classBack="invalid ";};
            classBack += thisClass;
          };
          return classBack;

        };

      //檢查是否至少已經設定了兩個字段之一
      //這是為郵政編碼字段和位址清單元素準備的
      function crossCheck(inTag,otherFieldID){
        if(!document.getElementById(otherFieldID)){return false;};
          return (inTag.value!="" || document.getElementById(otherFieldID).value!="")
        };

      //辨別出有問題的字段的标簽  
      function invalidLabel(parentTag){
        if(parentTag.nodeName=="LABEL"){
          //invalid前有空格
          parentTag.className += " invalid";
          };
        };

      //確定使用者選擇了一個單選按鈕
      function radioPicked(radioName){
        var radioSet="";
        //循環周遊表單,如果找到要找單選按鈕組,radio就會包含一個值
        for (var k=0;k<document.forms.length;k++){
          //将radioSet設定為正在檢視的表單中單選按鈕組的名稱
          if(!radioSet){
            radioSet=document.forms[k][radioName];
            };
          };
        //如果不能找到單選按鈕組,則傳回false,不能選擇單選按鈕
        if(!radioSet){return false;}
        //檢查每個單選按鈕,如果有一個被選中,則傳回true
        for(k=0;k<radioSet.length;k++){
          if(radioSet[k].checked){
            return true;
            };
          };
        //沒有發現被選中單選按鈕,則傳回false
          return false;
        };
      //驗證是否是數字 
      function isNum(passedVal){
        //如果字段是空的,那麼肯定不是數組,直接傳回False就可以了
        if (passedVal==""){return false;}
        for(var k=0; k<passedVal.length;k++)
        {   
             //charAt函數傳回字段位置K上的字元,檢查是否為數字
          if(passedVal.charAt(k)<"0"){return false;}
          if (passedVal.charAt(k)>"9"){return false;}
          };
            return true
        };

        //純javascript檢查郵箱(不使用正規表達式),隻是檢驗輸入的内容符合Email的正确形式,無法确認是否存在。
      function validEmail(email){
        //驗證是否存在空格,斜杠,冒号,都好分号等無效字元
        var invalidChars=" /:,;";
        if (email==""){return false;};
        for (var k=0;k<invalidChars.length;k++){
          var badChar=invalidChars.charAt(k);
          if(email.indexOf(badChar)>-1){return false;};
          };
        //驗證是否存在@
        var atPos=email.indexOf("@",1);
        if(atPos==-1){return false;};
        //驗證@是否重複存在
        if(email.indexOf("@",atPos+1)!=-1){return false;};
        //驗證是否存在點
        var periodPos=email.indexOf(".",atPos);
        if(periodPos==-1){return false;};
        //驗證點号後是否至少有兩個字元
        if(periodPos+3>email.length){return false;};
        return true;
        };
      //用正規表達式檢驗電子郵件位址(推薦使用)
      function isEmail(email){
        var reEmail=/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
        return reEmail.test(email);
        };
      //用正規表達式檢驗檔案字尾是否為gif或jpg
      function isImg(newURL){
        var reImg=/^(file|http):\/\/\S+\/\S+\.(gif|jpg)$/i;
        return reImg.test(newURL);
        };

        //驗證郵政編碼
      function isPostcode(postcode){
        var rePostcode=/^[0-9]{6}$/;
        return rePostcode.test(postcode);
        }


      //可以在這裡繼續擴充驗證内容,例如
      //驗證座機号碼
      //驗證手機
    };

  };
//根據使用者做出的選擇自動設定字段輸入
function spaceSet(){
  if(this.checked){
    document.getElementById("Space2").checked=true;
      }else
      {
    document.getElementById("Space2").checked=false;  
        };
  }      

注釋,我盡量寫得詳細些,大家應該能看明白。

可複用:

基本上囊括了表單上最常用的幾個控件的驗證方法.

可擴充,方法:

隻要在這個位置

加入你需要驗證的标簽的class屬性,

 然後在這裡,

添加你的驗證方法即可.

Html文檔:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>無标題文檔</title>
    <script type="text/javascript" src="ValidForm1.js"></script>
    <link rel="stylesheet" type="text/css" href="ValidForm.css">
</head>

<body>
<h2 >Valid Form</h2>
<form action="#">
    <p><label for="emailAddr">Email Address:
        <input id="emailAddr" type="text" size="30" class="reqd isEmail" />
        </label></p>

    <p><label for="color">Colors:
        <select id="color" class="reqd">
        <option value="" selected="selected">Choose a color</option>
        <option value="Red">Red</option>
         <option value="Green">Green</option>
          <option value="Blue">Blue</option>
          </select>
         </label></p>
    <p>Options:
        <label for="NormalUser"><input type="checkbox" id="NormalUser" value="Yes" />NormalUser(2G only)  </label>
         <label for="AdvancedUser"><input type="checkbox" id="AdvancedUser" value="Yes" />AdvancedUser</label></p>
     <p><label for="Space">Space:
     <input type="radio" id="Space2" name="Space" value="2G" class="radio" />2G  
     <input type="radio" id="Space4" name="Space" value="4G" class="radio" />4G
     </label></p>  

    <p><label for="address">Enter your Address or pick the Address<br />Address: <input type="text" id="address" size="30" maxlength="30" class="isAddress addressList"/>
       <select id="addressList" size="4" class="address">
        <option value="cangzhou">Cangzhou</option>
        <option value="langfang">Langfang</option>
        <option value="handan">Handan</option>
        <option value="baoding">Baoding</option>
        <option value="zhangjiakou">Zhangjiakou</option>
      </select>
     </label></p> 

    <p><label for="postcode">Postcode: <input id="postcode" type="text" size="6" maxlength="6" class="isPostcode" /></label></p>

      <p><label for="image">Image URL:<input id="image" type="text" size="30" maxlength="30" class="isImage" /></label></p>

      <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>

</body>
</html>
      

​CSS樣式表(ValidForm.css):​

@charset "utf-8";
/* CSS Document */
body{
  color:#000;
  background-color:#FFF;
}

input.invalid{
  /*當輸入無效時,使用該樣式*/
  background-color:#FF9;
  border:2px red inset;
}
label.invalid{
  /*當輸入無效時,使用該樣式*/
  color:#F00;
}      

歡迎拍磚!