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()执行默认提交表单处理。

相关文章
相关标签/搜索