JavaScript最初的一個應用場景就是分擔服務器處理表單的責任,打破到處依賴服務器的局面,這篇文章主要介紹zepto中
form
模塊關於表單處理的幾個方法,serialize
、serializeArray
、submit
。javascript
原文連接java
github項目地址 node
在開始學些form模塊相關方法前,咱們先來回顧一下表單提交時,瀏覽器是怎麼樣將數據發送給服務器的(如下內容摘自《JavaScript高級程序設計》第14章 14.4節 表單序列化)git
有了上面的知識的回顧,接下來咱們開始看zepto中serialize
和serializeArray
的實現github
由於serialize依賴serializeArray的實現,因此咱們先來看看它是怎麼實現的。而他的做用是把form表單序列化成一個由 name 和 value 屬性組成的對象的數組。形如:ajax
[ {name: 'qianlongo', value: 'haha'}, {name: 'wangmin', value: 'heihei'} ]
源代碼json
$.fn.serializeArray = function() { var name, type, result = [], add = function(value) { if (value.forEach) return value.forEach(add) result.push({ name: name, value: value }) } if (this[0]) $.each(this[0].elements, function(_, field){ type = field.type, name = field.name if (name && field.nodeName.toLowerCase() != 'fieldset' && !field.disabled && type != 'submit' && type != 'reset' && type != 'button' && type != 'file' && ((type != 'radio' && type != 'checkbox') || field.checked)) add($(field).val()) }) return result }
在$的原型上添加了serializeArray
相關方法。一開始聲明瞭name
,type
, result
三個變量,分別存儲表單控件的name屬性,type屬性,以及最後函數執行完成後要返回的數組。數組
首先經過this[0]
判斷有未選中表單元素,若是沒有返回的結果就是一個空數組了。若是選中了,則對該表單的相關控件(form.elements
表示表單中全部控件的集合)進行遍歷。瀏覽器
獲取單個控件的類型(type),name屬性(name),再接着就是判斷符合提交到服務器端的表單控件條件了。服務器
fieldset
元素在上面的條件都知足的條件下,調用add
函數並將經過$(elements).val()獲取到的值傳入。
add函數的邏輯也很是簡單。若是value是數組,則將value數組遞歸的每一項傳入add。不是數組就是直接按照{ name: name, value: value }
形式推入result了。
不過何時value會爲數組呢?咱們須要從zepto模塊的val函數實現看起
val函數實現
function val (value) { if (0 in arguments) { if (value == null) value = "" return this.each(function (idx) { this.value = funcArg(this, value, idx, this.value) }) } else { // 主要看這裏,multiple是用來設置下拉列表是否能夠多選的。 // 若是是多選的,則選擇被選中(即selected爲true)的元素並經過pluck方法,讀取該元素的value值,最後返回的是一個數組 return this[0] && (this[0].multiple ? $(this[0]).find('option').filter(function () { return this.selected }).pluck('value') : this[0].value) } }
將表單內容序列化爲查詢字符串。相似
name=qianlongo&sex=boy
源代碼
$.fn.serialize = function(){ var result = [] this.serializeArray().forEach(function(elm){ // 每一個表單的name和value都經過encodeURIComponent編碼 result.push(encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value)) }) // 最後經過&符號分割 return result.join('&') }
有了serializeArray
的基礎,serialize
就是將相應的name和value都經過encodeURIComponent
編碼,而後用&
符號進行分割,也就達到了咱們要的結果。
有兩種用法,當傳入了一個回調函數的時候,是給指定的表單的
submit
事件添加一個回調處理函數。若是沒有傳入回調函數則觸發當前表單
submit
事件,而且執行默認的提交表單行爲(前提是沒有阻止瀏覽器默認行爲)
源代碼
$.fn.submit = function(callback) { // 若是傳了回調函數,則在選中的元素上添加submit事件 if (0 in arguments) this.bind('submit', callback) // 不然在沒有傳遞迴調函數的狀況下,而且選中有表單元素 else if (this.length) { var event = $.Event('submit') // 觸發選中的第一個表單的是submit事件,注意這裏只是手動觸發綁定的submit事件,並不會提交表單 this.eq(0).trigger(event) // 若是沒有阻止默認事件,便調用form.submit()提交表單 if (!event.isDefaultPrevented()) this.get(0).submit() } return this }
以上是zepto form模塊的相關源碼分析,歡迎你們指正。
文章記錄
form模塊
zepto模塊
event模塊
ajax模塊