天天看點

用jQuery實作表單驗證

——選自《鋒利的jQuery》(第2版)第5章的例題

5.1.5 表單驗證

表單(form)作為 HTML 最重要的一個組成部分,幾乎在每個網頁上都有展現,例如使用者送出資訊、使用者回報資訊和使用者查詢資訊等,是以它是網站管理者與浏覽者之間溝通的橋梁。在表單中,表單驗證的作用也是非常重要的,它能使表單更加靈活、美觀和豐富。

以一個簡單的使用者注冊為例。首先建立一個表單, HTML 代碼如下:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>jQueryStudy</title>
    <style>
     .int{ height: 30px; text-align: left; width: 600px; }
     label{ width: 200px; margin-left: 20px; }
     .high{ color: red; }
     .msg{ font-size: 13px; }
     .onError{ color: red; }
     .onSuccess{ color: green; }
    </style>
    <script src="http://code.jquery.com/jquery-latest.js"></script>    
</head>
<body>
    <form method="post" action="#">
        <div class="int">
            <label for="name">姓名:</label>
            <input type="text" id="name" class="required" />
        </div>
        <div class="int">
            <label for="email">郵箱:</label>
            <input type="text" id="email" class="required" />
        </div>
        <div class="int">
            <label for="address">住址:</label>
            <input type="text" id="address" />
        </div>
        <div class="int">
            <input type="submit" value="送出" id="send" style="margin-left: 70px;" />
            <input type="reset" value="重置" id="res" />
        </div>
    </form>    
</body>
</html>      

顯示效果如下圖

用jQuery實作表單驗證

在表單内 class 屬性為 “required” 的文本框是必須填寫的,是以需要将它與其他的非必須填寫的表單元素加以差別,即在文本框後面追加一個紅色的星号辨別。可以使用 append() 方法來完成,代碼如下:

//為表單的必填文本框添加提示資訊(選擇form中的所有後代input元素)
    $("form :input.required").each(function () {
        //通過jquery api:$("HTML字元串") 建立jquery對象
        var $required = $("<strong class='high'>*</strong>");
        //添加到this對象的父級對象下
        $(this).parent().append($required);
    });      

顯示效果如下圖( 在必填元素後添加小紅星标記)

用jQuery實作表單驗證

使用者在“姓名”文本框中填寫完資訊後,将光标的焦點從“姓名”文本框中移出時,需要即時判斷姓名是否符合驗證規則。當光标的焦點從“郵箱”文本框移出時,也需要即時判斷“郵箱”填寫是否正确,是以需要給表單元素添加失去焦點事件,即 blur 事件。 jQuery 代碼如下:

//為表單的元素添加失去焦點事件
    $("form :input").blur(function () {
        // ...省略代碼
    });      

給表單裡的必填元素添加驗證功能的步驟如下:

(1)判斷目前失去焦點的元素是“姓名”還是“郵箱”,然後分别處理。    

 (2)如果是“姓名”,判斷元素的值的長度是否小于 6 ,如果小于 6 ,則用紅色字型提醒使用者輸入不正确,反之,則用綠色提醒使用者輸入正确。

 (3)如果是“郵箱”,判斷元素的值是否符合郵箱的格式,如果不符合,則用紅色字型提醒使用者輸入不正确,反之,則用綠色字型提醒使用者輸入正确。    

 (4)将提醒資訊追加到目前元素的父元素下面。      

【注】:為了使用友善,當 text 文本框中的内容格式錯誤時,程式應盡量把所有提示資訊都顯示出來,而不是每次驗證一種格式後隻顯示一個提示資訊。 不過有時為了提高響應性,也會每次隻顯示一個提示資訊。如:檢查使用者名是否重複,需要通路資料庫。

如何提示,需要依據具體的業務需求來确定。

根據以上分析,可以寫出如下 jQuery 代碼:

//為表單的必填文本框添加提示資訊(選擇form中的所有後代input元素)
        $("form :input.required").each(function () {
            //通過jquery api:$("HTML字元串") 建立jquery對象
            var $required = $("<strong class='high'>*</strong>");
            //添加到this對象的父級對象下
            $(this).parent().append($required);
        });

        //為表單元素添加失去焦點事件
        $("form :input").blur(function(){
            var $parent = $(this).parent();
            //驗證姓名
            if($(this).is("#name")){
                var nameVal = $.trim(this.value); //原生js去空格方式:this.replace(/(^\s*)|(\s*$)/g, "")
                var regName = /[~#^$@%&!*()<>:;'"{}【】  ]/;
                if(nameVal == "" || nameVal.length < 6 || regName.test(nameVal)){
                    var errorMsg = " 姓名非空,長度6位以上,不包含特殊字元!";
                    //class='msg onError' 中間的空格是層疊樣式的格式
                    $parent.append("<span class='msg onError'>" + errorMsg + "</span>");
                }
                else{
                    var okMsg=" 輸入正确";
                    $parent.find(".high").remove();
                    $parent.append("<span class='msg onSuccess'>" + okMsg + "</span>");
                }
            }
            //驗證郵箱
            if($(this).is("#email")){
                var emailVal = $.trim(this.value);
                var regEmail = /.+@.+\.[a-zA-Z]{2,4}$/;
                if(emailVal== "" || (emailVal != "" && !regEmail.test(emailVal))){
                    var errorMsg = " 請輸入正确的E-Mail住址!";
                    $parent.append("<span class='msg onError'>" + errorMsg + "</span>");
                }
                else{
                    var okMsg=" 輸入正确";
                    $parent.find(".high").remove();
                    $parent.append("<span class='msg onSuccess'>" + okMsg + "</span>");
                }
            }
        });      

當連續幾次輸入錯誤的格式後,會出現如下圖 所示的效果

用jQuery實作表單驗證

由于每次在元素失去焦點後,都會建立一個新的提醒元素,然後将它追加到文檔中,最後就出現了多次的提醒資訊。是以,需要在建立提醒元素之前,将目前元素以前的提醒元素都删除。可以使用 remove() 方法來完成,代碼如下:

//為表單元素添加失去焦點事件
$("form :input").blur(function(){ 
    var $parent = $(this).parent();
    $parent.find(".msg").remove(); //删除以前的提醒元素(find():查找比對元素集中元素的所有比對元素)
    // ...省略代碼
});      

顯示如下(正确的效果)

用jQuery實作表單驗證

當滑鼠在表單元素中多次失去焦點時,都可以提醒使用者填寫是否正确。但是,如果使用者無視錯誤提醒,執意要單擊“送出”按鈕時,為了使表單填寫準确,在表單送出之前,需要對表單的必須填寫元素進行一次整體的驗證。可以直接用 trigger() 方法來觸發blur事件,進而達到驗證效果。如果填寫錯誤,就會以紅色提醒使用者;如果姓名和郵箱都不符合規則,那麼就有兩處錯誤,即有兩個 class 為 “onError” 的元素,是以可以根據 class 為 “onError” 元素的長度來判斷是否可以送出。如果長度為 0 ,即 true ,說明已經可以送出了;如果長度大于0,即 false ,說明有錯誤,需要阻止表單送出。阻止表單送出可以直接用 “return false” 語句。

根據上面的分析,可以在送出事件中寫出如下jQuery代碼:

//點選重置按鈕時,通過trigger()來觸發文本框的失去焦點事件
$("#send").click(function(){
    //trigger 事件執行完後,浏覽器會為submit按鈕獲得焦點
    $("form .required:input").trigger("blur"); 
    var numError = $("form .onError").length;
    if(numError){
        return false;
    }
    alert("注冊成功!");
});      

顯示如下(驗證通過)

用jQuery實作表單驗證

使用者也許會提出:為什麼每次都要等字段元素失去焦點後,才提醒是否正确?如果輸入時就可以提醒,這樣就可以更加即時了。

為了達到使用者提出的需求,需要給表單元素綁定 keyup 事件和 focus 事件,keyup 事件能在使用者每次松開按鍵時觸發,實作即時提醒;focus 事件能在元素得到焦點的時候觸發,也可以實作即時提醒。

代碼如下:

$("form :input").blur(function(){ 
    //失去焦點處理函數
    //代碼省略...
}).keyup(function(){
    //triggerHandler 防止事件執行完後,浏覽器自動為标簽獲得焦點
    $(this).triggerHandler("blur"); 
}).focus(function(){
    $(this).triggerHandler("blur");
});      

這樣當使用者将光标定位到文本框上和改變文本框的值時,表單就會即時提醒使用者填寫是否正确,進而符合了使用者的需求。

在前面的章節已經提過,trigger(“blur”)不僅會觸發為元素綁定的blur事件,也會觸發浏覽器預設的 blur 事件,即不能講光标定位到文本框上。而 triggerHandler(“blur”)隻會觸發為元素綁定的 blur 事件,而不觸發浏覽器預設的 blur 事件。

至此,表單驗證過程就全部完成。讀者可以根據自己的實際需求修改驗證規則。

【注】:用戶端的驗證僅用于提升使用者的操作體驗,而伺服器仍需對使用者輸入的資料的合法性進行校驗。對于禁用了腳本的使用者和使用者自制的網頁送出操作,必須在伺服器端驗證。

完整代碼:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>jQueryStudy</title>
    <style>
     .int{ height: 30px; text-align: left; width: 600px; }
     label{ width: 200px; margin-left: 20px; }
     .high{ color: red; }
     .msg{ font-size: 13px; }
     .onError{ color: red; }
     .onSuccess{ color: green; }
    </style>
    <script src="http://code.jquery.com/jquery-latest.js"></script>    
</head>
<body>
    <form method="post" action="#">
        <div class="int">
            <label for="name">姓名:</label>
            <input type="text" id="name" class="required" />
        </div>
        <div class="int">
            <label for="email">郵箱:</label>
            <input type="text" id="email" class="required" />
        </div>
        <div class="int">
            <label for="address">住址:</label>
            <input type="text" id="address" />
        </div>
        <div class="int">
            <input type="submit" value="送出" id="send" style="margin-left: 70px;" />
            <input type="reset" value="重置" id="res" />
        </div>
    </form>
    <script>
        //為表單的必填文本框添加提示資訊(選擇form中的所有後代input元素)
        $("form :input.required").each(function () {
            //通過jquery api:$("HTML字元串") 建立jquery對象
            var $required = $("<strong class='high'>*</strong>");
            //添加到this對象的父級對象下
            $(this).parent().append($required);
        });

        //為表單元素添加失去焦點事件
        $("form :input").blur(function(){
            var $parent = $(this).parent();
            $parent.find(".msg").remove(); //删除以前的提醒元素(find():查找比對元素集中元素的所有比對元素)
            //驗證姓名
            if($(this).is("#name")){
                var nameVal = $.trim(this.value); //原生js去空格方式:this.replace(/(^\s*)|(\s*$)/g, "")
                var regName = /[~#^$@%&!*()<>:;'"{}【】  ]/;
                if(nameVal == "" || nameVal.length < 6 || regName.test(nameVal)){
                    var errorMsg = " 姓名非空,長度6位以上,不包含特殊字元!";
                    //class='msg onError' 中間的空格是層疊樣式的格式
                    $parent.append("<span class='msg onError'>" + errorMsg + "</span>");
                }
                else{
                    var okMsg=" 輸入正确";
                    $parent.find(".high").remove();
                    $parent.append("<span class='msg onSuccess'>" + okMsg + "</span>");
                }
            }
            //驗證郵箱
            if($(this).is("#email")){
                var emailVal = $.trim(this.value);
                var regEmail = /.+@.+\.[a-zA-Z]{2,4}$/;
                if(emailVal== "" || (emailVal != "" && !regEmail.test(emailVal))){
                    var errorMsg = " 請輸入正确的E-Mail住址!";
                    $parent.append("<span class='msg onError'>" + errorMsg + "</span>");
                }
                else{
                    var okMsg=" 輸入正确";
                    $parent.find(".high").remove();
                    $parent.append("<span class='msg onSuccess'>" + okMsg + "</span>");
                }
            }
        }).keyup(function(){
            //triggerHandler 防止事件執行完後,浏覽器自動為标簽獲得焦點
            $(this).triggerHandler("blur"); 
        }).focus(function(){
            $(this).triggerHandler("blur");
        });
        
        //點選重置按鈕時,通過trigger()來觸發文本框的失去焦點事件
        $("#send").click(function(){
            //trigger 事件執行完後,浏覽器會為submit按鈕獲得焦點
            $("form .required:input").trigger("blur"); 
            var numError = $("form .onError").length;
            if(numError){
                return false;
            }
            alert("注冊成功!");
        });
    </script>
</body>
</html>      

更多資源: