zepto源碼研究 - form.js

簡要:form.js的主要功能是序列化form表單裏面字段和註冊submit事件以及觸發表單提交事件。以下源碼:node

//     Zepto.js
//     (c) 2010-2015 Thomas Fuchs
//     Zepto.js may be freely distributed under the MIT license.

;(function($){

  /**
   * 序列表單內容爲JSON數組
   * 返回相似[{a1:1},{a2:2}]的數組
   * @returns {Array}
   */
  $.fn.serializeArray = function() {
    var name, type, result = [],

    //{name:value}形式加入到結果數組中
        add = function(value) {
          //value是數組,遞歸添加到數組中
          //注意這裏的寫法    value.forEach(add)   將value數組遞歸的每一項傳入add
          // 如 {a:[1,2,3]} -->  [{a:1},{a:2},{a:3}]
          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

      //排除fieldset,禁用元素,submit,reset,button,file和未被選中的radio,checkbox
      //緣由是這些元素不須要傳遞給服務器
      if (name && field.nodeName.toLowerCase() != 'fieldset' &&
          !field.disabled && type != 'submit' && type != 'reset' && type != 'button' && type != 'file' &&

          ((type != 'radio' && type != 'checkbox') || field.checked))

      //{name:value}形式加入到結果數組中
        add($(field).val())
    })
    return result
  }

  /**
   * 序列表表單內容爲查詢字符串
   *  轉換成 a=1&b=2
   * @returns {string}
   */
  $.fn.serialize = function(){
    var result = []
    this.serializeArray().forEach(function(elm){
      // 每一個key-value,都保守URI編碼
      result.push(encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value))
    })
    return result.join('&')
  }

  /**
   * 提交表單
   * @param callback
   * @returns {*}
   */
  $.fn.submit = function(callback) {
    //0 in arguments 判斷是否傳了回調函數
//      這裏不該用bind,全部事件應該統一用on
    //傳了回調,就當成綁定submit事件
    if (0 in arguments) this.bind('submit', callback)
    //沒有傳回調,當成直接提交
    else if (this.length) {//有表單元素
      var event = $.Event('submit')

      //第一個表單直接觸發submit事件
      //若是綁定過submit事件,此處會執行submit綁定函數
      //注意,這裏只是拋出事件,並不會提交表單
      this.eq(0).trigger(event)

      //若是未阻止瀏覽器默認事件,調用document.forms[0].submit()執行默認處理
      //document.forms[0].submit()提交表單
      if (!event.isDefaultPrevented()) this.get(0).submit()
    }
    return this
  }

})(Zepto)

serializeArray:數組

1:add = function(value) { if (value.forEach) return value.forEach(add) result.push({ name: name, value: value })}
     value.forEach 循環遞歸add解決value爲數組的狀況,這是一個小技巧。瀏覽器

2:formObject.elements : 爲包含表單裏面全部字段節點的數組。服務器

提示:若是 elements[] 數組具備名稱(input 標籤的 id 或 name 屬性),那麼該元素的名稱就是 formObject 的一個屬性,所以能夠使用名稱而不是數字來引用 input 對象。函數

舉例,假設 x 是一個 form 對象,其中的一個 input 對象的名稱是 fname,則能夠使用 x.fname 來引用該對象this

 

serialize編碼

 

result.join('&'):這裏要將一個map格式的數據轉化爲a=1&b=2,可將a=2,b=3等相同格式的項封裝做爲數組,再用join("&"),將&插入形參字符串。spa

 

submit:code

$.Event是建立事件,trigger(event)拋出事件,並不會提交表單。orm

document.forms[0].submit()執行默認提交表單處理。

相關文章
相關標籤/搜索