您的位置:首页 > Web前端 > JQuery

读Zepto源码之Form模块

2017-10-24 15:28 399 查看
Form
模块处理的是表单提交。表单提交包含两部分,一部分是格式化表单数据,另一部分是触发
submit
事件,提交表单。

读 Zepto 源码系列文章已经放到了github上,欢迎star: reading-zepto

源码版本

本文阅读的源码为 zepto1.2.0

GitBook

reading-zepto

.serializeArray()

$.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
是格式化部分的核心方法,后面的
serialize
方法内部调用的也是
serializeArray
方法。

serializeArray
最终返回的结果是一个数组,每个数组项为包含
name
value
属性的对象。其中
name
为表单元素的
name
属性值。

add函数

add = function(value) {
if (value.forEach) return value.forEach(add)
result.push({ name: name, value: value })
}


表单的值交由
add
函数处理,如果值为数组(支持
forEach
) 方法,则调用
forEach
遍历,继续由
add
函数处理。否则将结果存入数组
result
中。最后返回的结果也是这个
result


遍历表单元素

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())
})


如果集合中有多个表单,则只处理第一个表单的表单元素。
this[0].elements
用来获取第一个表单所有的表单元素。

type
为表单类型,
name
为表单元素的
name
属性值。

这一大段代码的关键在
if
中的条件判断,其实是将一些无关的表单元素排除,只处理符合条件的表单元素。

以下一个条件一个条件来分析:

field.nodeName.toLowerCase() != 'fieldset'
排除
fieldset
元素;

!field.disabled
排除禁用的表单,已经禁用了,肯定是没有值需要提交的了;

type != 'submit'
排除确定按钮;

type != 'reset'
排除重置按钮;

type != 'button'
排除按钮;

type != 'file'
排除文件选择控件;

((type != 'radio' && type != 'checkbox') || field.checked))
如果是
radio
checkbox
时,则必须要选中,这个也很好理解,如果没有选中,也不会有值需要处理。

然后调用
add
方法,将表单元素的值获取到交由其处理。

.serialize()

$.fn.serialize = function(){
var result = []
this.serializeArray().forEach(function(elm){
result.push(encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value))
})
return result.join('&')
}


表单元素处理完成后,最终是要拼成如
name1=value1&name2=value2&...
的形式,
serialize
方法要做的就是这部分事情。

这里对
serizlizeArray
返回的数组再做进一步的处理,首先用
encodeURIComponent
序列化
name
value
的值,并用
=
号拼接成字符串,存进新的数组中,最后调用
join
方法,用
&
将各项拼接起来。

.submit()

$.fn.submit = function(callback) {
if (0 in arguments) this.bind('submit', callback)
else if (this.length) {
var event = $.Event('submit')
this.eq(0).trigger(event)
if (!event.isDefaultPrevented()) this.get(0).submit()
}
return this
}


处理完数据,接下来该到提交了。

if (0 in arguments) this.bind('submit', callback)


如果有传递回调函数
callback
,则在表单上绑定
submit
事件,以
callback
作为事件的回调。

else if (this.length) {
var event = $.Event('submit')
this.eq(0).trigger(event)
if (!event.isDefaultPrevented()) this.get(0).submit()
}


否则手动绑定
submit
事件,如果没有阻止浏览器的默认事件,则在第一个表单上触发
submit
,提交表单。

注意
eq
get
的区别,
eq
返回的是
Zepto
对象,而
get
返回的是
DOM
元素。

系列文章

读Zepto源码之代码结构

读Zepto源码之内部方法

读Zepto源码之工具函数

读Zepto源码之神奇的$

读Zepto源码之集合操作

读Zepto源码之集合元素查找

读Zepto源码之操作DOM

读Zepto源码之样式操作

读Zepto源码之属性操作

读Zepto源码之Event模块

读Zepto源码之IE模块

读Zepto源码之Callbacks模块

读Zepto源码之Deferred模块

读Zepto源码之Ajax模块

读Zepto源码之Assets模块

读Zepto源码之Selector模块

读Zepto源码之Touch模块

读Zepto源码之Gesture模块

读Zepto源码之IOS3模块

读Zepto源码之Fx模块

读Zepto源码之fx_methods模块

读Zepto源码之Stack模块

附文

译:怎样处理 Safari 移动端对图片资源的限制

参考

zepto源码分析之form模块

HTMLFormElement.elements

License

署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)

最后,所有文章都会同步发送到微信公众号上,欢迎关注,欢迎提意见:


作者:对角另一面
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息