jquery.form.js詳細講解

如今你們在在表單提交的時候都不流行中間頁面作跳轉(好比發佈成功的提示頁面),或者說這樣作會下降用戶體驗。因此通常都是採用ajax來提交,能看到這個頁面的朋友,想必對ajax提交表單已是很熟悉了。javascript

若是是表單的值是修改密碼這種,表單的值比較少,還好,咱們能夠經過php

$.post(url,{password:password},function(data){})html

這樣來作處理,若是一個表單有20個input須要輸入,並且還有不少input表單的name名是二維數組,例如<input name="info[name]" >這樣的。咱們應該怎麼辦呢?html5

若是使用jquery,知道jquery提供了一個$("form").serializeArray()的方法,能夠用在這裏解決。可是還須要本身來作一些處理。java

若是使用jquery.form.js來作提交的話,就能夠省略這幾步啦,無論表單多複雜,它都幫咱們封裝好發送的機制了。jquery

讓咱們在發送表單的時候感受就像是直接發送post同樣!ajax

好比這邊發送的是<input name="info[name]">的值數組

在php端,則能夠直接使用$_POST['info']['name']來獲取了。瀏覽器

在表單提交前,能夠設置beforeSubmit和beforeSerialize。緩存

能夠在beforeSerialize組裝發送的表單值以前修改某些表單的值.

也能夠在beforeSubmit能夠作表單提交前的驗證,不經過則能夠阻止表單的提交

 

 

 

 

jQuery異步提交表單

如今咱們已經意識到使用同步方式提交表單會形成出現「白頁」的糟糕用戶體驗,那好,如今我使用上一篇分享的技術《觸碰jQuery:AJAX異步詳解》來將上面同步提交表單調整爲異步提交表單的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
< form id="form1" method="post">
     < table border="1">
         < tr >
             < td >用戶名:</ td >
             < td >
                 < input type="text" name="loginName" /></ td >
         </ tr >
         < tr >
             < td >愛  好:</ td >
             < td >
                 < input type="checkbox" name="cbLoveYy" value="1" />游泳
                 < input type="checkbox" name="cbLoveYx" value="1" />遊戲
                 < input type="checkbox" name="cbLovePs" value="1" />登山
             </ td >
         </ tr >
         < tr >
             < td colspan="2" style="text-align: center">
                 < input id="btnAjaxSubmit" type="submit" value="jQuery.ajax提交" />
             </ td >
         </ tr >
     </ table >
</ form >

jQuery提交代碼以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script type= "text/javascript" >
     $(document).ready( function () {
         $( "#btnAjaxSubmit" ).click( function () {
             var options = {
                 url: 'async_submit_test1.aspx?action=SaveUserInfo' ,
                 type: 'post' ,
                 dataType: 'text' ,
                 data: $( "#form1" ).serialize(),
                 success: function (data) {
                     if (data.length > 0)
                         $( "#responseText" ).text(data);
                 }
             };
             $.ajax(options);
             return false ;
         });
     });
</script>

咱們經過$("#form1").serialize()將表單元素的數據轉化爲字符串,而後經過$.ajax()執行異步請求資源。

方案:jQuery.ajax() + .aspx請求

此方案優點:

1)         咱們不會感受頁面的「閃一閃」效果

2)         咱們不會由於服務器耗時響應而致使出現「百頁」的糟糕用戶體驗。

此方案劣勢:

1)         此方案中我仍是使用了aspx頁面去響應請求,只是在後臺經過action參數去作相應處理,儘管是異步操做但卻完完整整的跑了一遍ASP.NET頁面生命週期(這也是在Response.Write()輸出完本身的東西后必須調用Response.End();來提早終止生命週期,不然頁面信息也會一塊兒返回)

2)         jQuery庫提供的序列化表單字符串方法不能收集文件上傳的表單元素,如,$("#form1").serialize()。因此對於包含文件上傳的表單咱們還需經過<iframe>模擬異步表單提交。(<iframe>模擬異步表單提交的過程我將在分析jQuery.form插件的源碼小節進行說明)

(jQuery庫提供的序列化字符串的數據來源時表單的elements屬性,而<input type=」file」 />的表單元素不包含在elements中)

 

         固然jQuery.ajax()也能夠結合.ashx文件(通常處理文件)或其餘方式實現高效異步請求,這邊只是爲了說明:異步請求aspx頁面也會跑一邊aspx頁面生命週期的事實。

 

jQuery.form插件輕鬆實現表單提交

         如今咱們使用jQuery的表單插件Jquery.form.js(官網)來實現異步表單提交。

1)         該插件須要Jquery最低版本爲v1.5

2)         該插件提供了ajaxSubmit和ajaxForm兩種表單提交方式,但不要對同一個表單同時使用兩種方式。

如今我將經過「jQuery+jQuery.form插件+ashx(通常處理文件)」來實現一個高效的異步表單提交。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
< form id="form1" action="ajaxOperation.ashx" method="post">
     < table border="1">
         < caption >jQuery.form.js異步提交方式</ caption >
         < tr >
             < td >用戶名:</ td >
             < td >
                 < input type="text" name="loginName" /></ td >
         </ tr >
         < tr >
             < td colspan="2" style="text-align: center">
                 < button id="btnAjaxSubmit">ajaxSubmit提交</ button >
                 &nbsp;
                 < input id="btnAjaxForm" type="submit" value="ajaxForm提交" />
             </ td >
         </ tr >
     </ table >
</ form >

1)         爲<form>標籤指定action值,指定使用ajaxOperation.ashx處理該表單請求。

2)         使用兩個提交按鈕btnAjaxSubmit和btnAjaxForm分別對應jQuery.form插件提供的兩種表單提交API。

jQuery表單插件提交代碼以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script type= "text/javascript" >
     $(document).ready( function () {
     var options = {
         success: function (data) {
             $( "#responseText" ).text(data);
         }
     };
 
         // ajaxForm
         $( "#form1" ).ajaxForm(options);
 
         // ajaxSubmit
         $( "#btnAjaxSubmit" ).click( function () {
             $( "#form1" ).ajaxSubmit(options);
         });
     });
</script>

方案:jQuery.form.js插件 + .ashx請求

         此方案優點:

1)         簡簡單單幾句代碼,咱們就能夠實現表單的提交,而且可靈活經過ajaxSubmit()函數基於任何事件的觸發實現表單異步提交。

2)         支持文件上傳功能,並在新瀏覽器中支持進度條更新。(在jQuery.form插件源碼分析中會進行說明)

3)         與jQuery庫完美結合,支持jQuery.ajax()函數觸發的各類事件,支持jQuery.ajax()中所傳遞的參數。(在jQuery.form插件源碼分析中會進行說明)

          

         好了,這樣短而易讀的代碼,這樣的偷懶方式不正是咱們追求的嗎?那jQuery.form插件提供的表單提交API是否高效呢?內部又作了些什麼?接下來跟着我看看jQuery.form插件內部實現吧。。。

 

jQuery.form插件源碼分析

         jQuery.form插件(Jquery.form.js 官網),可讓咱們很是簡單的實現表單的異步提交、實現文件上傳、進度條顯示等等功能。

 

  1. $(「form1」).ajaxSubmit(options)

1)         ajaxSubmit是jQuery表單插件核心函數。很是靈活,由於它依賴於事件機制,只要有事件觸發就能使用ajaxSubmit()提交表單,eg:超連接、圖片、按鈕的click事件。

2)         options參數是

a)         一個函數,則爲表單提交成功後調用的回調函數,即,options={success:function}。

b)         options參數是一個集合,一個參數鍵值對

鍵名

描述

type

(默認爲表單的method屬性值,若未設置取GET)

請求的類型,例如:POST、GET、PUT及PROPFIND。大小寫不敏感。

url

(默認取表單的action屬性值,若未設置默認取window.location.href)

請求的URL地址,能夠爲絕對地址也能夠爲相對地址。

data

(對象成員必須包含name和value屬性)提供額外數據對象,經過$.param()函數返回序列化後的字符串,稍後會拼接到表單元素序列化的字符串以後。

extraData

(此參數無需外部提供,由內部處理)

此參數是data在進行序列化成字符串以前的一個拷貝,只用於在表單包含<input type=」file」 />而且是老瀏覽器。

由於在老瀏覽器中文件上傳文件咱們須要經過<iframe>來模擬異步提交,此時extraData會轉變爲<input type=」hidden」 />元素包含在表單中,被一塊兒提交到服務器。

dataType

通常不需本身設置。參數做用請看:《jQuery.ajax()-dataType》

traditional

若是你想要用傳統的方式來序列化數據,那麼就設置爲true。請參考$.param()深度遞歸詳解

delegation

(適用於ajaxForm)ajaxForm支持Jquery插件的委託方式(須要Jquery v1.7+),因此當你調用ajaxForm的時候其表單form不必定存在,但動態構建的form會在適當的時候調用ajaxSubmit。Eg:

1
2
3
4
$( '#myForm' ).ajaxForm({
     delegation: true ,
     target: '#output'
});

replaceTarget

(默認:false)與target參數共同起做用,True則執行replaceWirh()函數,false則執行html()函數

target

提供一個Html元素,在請求「成功」而且未設置dataType參數,則將返回的數據replaceWith()或html()掉對象原來的內容,再遍歷對象調用success回調函數。

1
2
3
4
5
6
7
if (!options.dataType && options.target) {
     var oldSuccess = options.success || function (){};
     callbacks.push( function (data) {
         var fn = options.replaceTarget ? 'replaceWith' : 'html' ;
         $(options.target)[fn](data).each(oldSuccess, arguments);
     });
}

includeHidden

在請求成功後,若設置執行clearForm()函數清空表單元素則會根據includeHidden設置決定如何清空隱藏域元素。

1)         傳遞true,表示清空表單的全部隱藏域元素。

2)         傳遞字符串,表示清空特殊匹配的隱藏域表單元素,eg: $('#myForm').clearForm('.special:hidden'),清空class屬性包含special值的隱藏域

clearForm

請求成功時觸發(同success),並用options. includeHidden作爲回調函數參數。

回調函數:$form.clearForm(options.includeHidden);

resetForm

請求成功時觸發(同success)。

回調函數:$form.resetForm()

semantic

布爾值,指示表單元素序列化時是否嚴格按照表單元素定義順序。

在序列化只有<input type=」image」 />元素會放在序列化字符串的最後,若semantic=true,則會按照它的定義順序進行序列化。

若你服務器嚴格要求表單序列化字符串的順序,則使用此參數進行控制。

iframe

(默認:false)如有文件上傳'input[type=file]:enabled[value!=""]',指示是否應該使用<iframe>標籤(在支持html5文件上傳新特性的瀏覽器中不會使用iframe模式)

iframeTarget

指定一個現有的<iframe>元素,不然將自動生成一個<iframe>元素以及name屬性值。若現有的<iframe>元素沒有設置name屬性,則會自動生成一個name值

iframeSrc

爲<iframe>元素設定src屬性值

 

回調函數

beforeSerialize

提供在將表單元素序列化爲字符串以前,處理表單元素的回調函數。

簽名:function(form,options)

函數說明:當前表單對象、options參數集合

返回值:返回false,表示終止表單提交操做。

beforeSubmit

提供在執行表單提交以前,處理數據的回調函數。

簽名:function(a,form,options)

函數說明:經過formToArray(options.semantic, elements)返回的表單元素數組、當前表單對象、options參數集合

返回值:返回false,表示終止表單提交操做。

3)         $(「form1」).ajaxSubmit(options) 內部直接或模擬jQuery.ajax(options)異步提交,因此也直接支持jQuery.ajax(options)所能處理的參數,而且支持jQuery.ajax(options)過程當中所觸發的5個局部事件及6個全局事件

4)         $(「form1」).ajaxSubmit(options) 內部將內部直接調用jQuery.ajax(options)返回的jqxhr對象或模擬的jqxhr對象進行了緩存,因此咱們能夠經過$(「#form1」).data(‘jqxhr’)獲取到本次提交生成的jqxhr對象。

5)         更多jQuery.ajax()函數介紹請看:《觸碰jQuery:AJAX異步詳解》

 

ajaxSubmit函數處理流程:

1)         根據<form action=」」 method=」」>處理url、type參數以及success、iframeSrc等參數。

2)         觸發beforeSerialize()回調函數

3)         序列化data參數和表單元素

4)         觸發beforeSubmit()回調函數

5)         根據type參數處理options.data和options.url參數

6)         註冊resetForm()和clearForm()回調函數

7)         註冊將返回數據加載到options.target指定的元素上的回調函數

8)         註冊success回調函數,如有options.target則循環該元素,併爲每一個子元素註冊success回調函數

9)         處理<input type=」file」 />文件上傳元素

a)         不包含文件元素,直接調用jQuery.ajax()函數。

b)         包含文件元素,而且不支持XMLHttpRequest Level 2提供的文件上傳新特性window.FormData。則經過IFrame模擬表單異步提交

                                       i.              調用fileUploadIframe()函數。

                                     ii.              根據options. iframeTarget設置決定是建立一個<iframe>元素仍是使用現有的<iframe>元素

                                    iii.              模擬xhr對象以及jQuery.ajax()過程,以支持xhr對象返回和ajax事件觸發

                                    iv.              設置<form>的target指向<iframe>元素、encoding和enctype爲「multipart/form-data」、method爲」post」值等等

                                     v.              處理options.extraData爲<input type=」hidden」 />元素並添加到<form>元素中。

                                    vi.              調用<form>的submit()事件。(同步提交,但由於<form>的target指向<iframe>標籤,因此刷新的是<iframe>中的內容,以此模擬異步提交)

c)         包含文件元素,而且支持XMLHttpRequest Level 2提供的新特性,則調用fileUploadXhr()函數,經過FormData()對象將數據傳遞給options.data參數,再調用jQuery.ajax(options)函數異步提交表單。而且XMLHttpRequest Level 2的新特性還支持進度條提示功能。(更多新特性請看:《XMLHttpRequest Level 2 使用指南》

10)     將內部jqxhr緩存起來,以供訪問。$form.removeData('jqxhr').data('jqxhr', jqxhr);

11)     返回表單元素自己,以便符合jQuery的鏈式操做模式。

 

  1. $(「form1」).ajaxForm(options)

是對$(「any」).ajaxSubmit(options)函數的一個封裝,適用於表單提交的方式(注意,主體對象是<form>),會幫你管理表單的submit和提交元素([type=submit],[type=image])的click事件。在出發表單的submit事件時:阻止submit()事件的默認行爲(同步提交的行爲)而且調用$(this).ajaxSubmit(options)函數。

ajaxForm支持Jquery插件的委託方式(須要Jquery v1.7+),因此當你調用ajaxForm的時候其表單form不必定存在,ajaxSubmit將在適當的時候調用。Eg:

1
2
3
4
$( '#myForm' ).ajaxForm({
     delegation: true ,
     target: '#output'
});

         另外:若是你翻看原來碼你可能會發現這樣的綁定代碼:.bind('submit.form-plugin', options, doAjaxSubmit),即submit事件名後面有個」. form-plugin」。這是jQuery事件命名空間語法,做用是方便事件的管理。

 

文件上傳示例(被jQuery.form插件封裝的至關簡單,既然寫了就也貼出來吧)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
< form id="form1" action="ajaxOperation.ashx?Action=formUpload" method="post" enctype="multipart/form-data">
     < table >
         < tr >
             < td >附件名字:</ td >
             < td >
                 < input type="text" name="fileName" /></ td >
         </ tr >
         < tr >
             < td >附件:</ td >
             < td >
                 < input type="file" name="document" /></ td >
         </ tr >
         < tr >
             < td colspan="2" style="align-content: center">
                 < input type="submit" value="模擬iframe提交表單" />
             </ td >
         </ tr >
     </ table >
</ form >
< label id="responseText"></ label >

         提交代碼:

1
2
3
4
5
6
7
8
9
10
11
<script type= "text/javascript" >
     $( function () {
         var options = {
             success: function (data) {
                 $( "#responseText" ).text(data);
             }
         };
 
         $( "#form1" ).ajaxForm(options);
     });
</script>

 

  1. $(「form1」).ajaxFormUnbind()

                   取消$(「」).ajaxForm(options)函數對指定表單綁定的submit和click事件。

                                                                             

  1. $(「form1」).formToArray(semantic,elements)

                   序列化當前表單元素到一個數組中,每一個數組元素都是包含name和value屬性的對象。返回值是內部構件的一個數組元素,而elements參數將包含除<input type=」image」>之外的全部表單元素。

 

  1. $(「form1」).formSerialize(semantic)

將表當前單元素序列化爲字符串形式。

實現以下:

1
2
3
$.fn.formSerialize = function (semantic) {
     return $.param( this .formToArray(semantic));
};

 

  1. $(「form1」).fieldSerialize(successful)  

                   序列化包含name屬性的表單元素爲一個字符串。Successful參數標識是否獲取type爲reset、button、checkbox、radio、submit、image值得元素以及<select>的值。返回$(el).val()。

 

  1. $(「form1」).fieldValue(successful) 或 $.fieldValue(element, successful)

獲取指定表單中的表單元素或指定表單元素的值。Successful參數標識是否獲取type爲reset、button、checkbox、radio、submit、image值得元素以及<select>的值。返回$(el).val()。

 

  1. $(「form1」).clearForm(includeHidden)

清空當前表單中input、select、textarea元素的值。includeHidden設置決定如何清空隱藏域元素。

a)         傳遞true,表示清空表單的全部隱藏域元素。

b)         傳遞字符串,表示清空特殊匹配的隱藏域表單元素,eg: $('#myForm').clearForm('.special:hidden'),清空class屬性包含special值的隱藏域

 

  1. $.(「form1」).clearFields(includeHidden) 和 $.(「form1」).clearInputs(includeHidden)

做用相同,清空當前表單中全部表單元素的指。includeHidden設置決定如何清空隱藏域元素。

a)         傳遞true,表示清空表單的全部隱藏域元素。

b)         傳遞字符串,表示清空特殊匹配的隱藏域表單元素,eg: $('#myForm').clearForm('.special:hidden'),清空class屬性包含special值的隱藏域

 

  1. $(「form1」).resetForm()

重置當前表單元素,致使全部表單元素重置到它的初始值。

 

  1. $(「form1」).selected(select)

將當前表單元素中全部checkbox、radio設置爲select。select參數爲布爾值。

 

 

 

         本文到此結束,經過此博文相信各位,

  1. 不再會去寫齷齪的同步提交和使用aspx進行異步相應了。
  2. 不再用煩惱表單提交過程當中各個控件的值如何獲取的問題,而且經過jQuery.form表單插件輕鬆實現表單異步提交、文件上傳及進度條顯示。
  3. 清楚的認識了jQuery.form表單在給咱們提供便利的背後到底作了什麼手腳(源碼分析)。
相關文章
相關標籤/搜索