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模块