读Zepto源码之Form模块

本文解析了Zepto中表单处理的核心方法,包括格式化表单数据和提交表单的过程。详细介绍了.serializeArray()、.serialize() 和 .submit() 方法的工作原理。

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 最终返回的结果是一个数组,每个数组项为包含 namevalue 属性的对象。其中 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)) 如果是 radiocheckbox 时,则必须要选中,这个也很好理解,如果没有选中,也不会有值需要处理。

然后调用 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 序列化 namevalue 的值,并用 = 号拼接成字符串,存进新的数组中,最后调用 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 ,提交表单。

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

系列文章

  1. 读Zepto源码之代码结构
  2. 读Zepto源码之内部方法
  3. 读Zepto源码之工具函数
  4. 读Zepto源码之神奇的$
  5. 读Zepto源码之集合操作
  6. 读Zepto源码之集合元素查找
  7. 读Zepto源码之操作DOM
  8. 读Zepto源码之样式操作
  9. 读Zepto源码之属性操作
  10. 读Zepto源码之Event模块
  11. 读Zepto源码之IE模块
  12. 读Zepto源码之Callbacks模块
  13. 读Zepto源码之Deferred模块
  14. 读Zepto源码之Ajax模块
  15. 读Zepto源码之Assets模块
  16. 读Zepto源码之Selector模块
  17. 读Zepto源码之Touch模块
  18. 读Zepto源码之Gesture模块
  19. 读Zepto源码之IOS3模块
  20. 读Zepto源码之Fx模块
  21. 读Zepto源码之fx_methods模块
  22. 读Zepto源码之Stack模块

附文

参考

License

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

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

作者:对角另一面

标题基于Python的自主学习系统后端设计与实现AI更换标题第1章引言介绍自主学习系统的研究背景、意义、现状以及本文的研究方法和创新点。1.1研究背景与意义阐述自主学习系统在教育技术领域的重要性和应用价值。1.2国内外研究现状分析国内外在自主学习系统后端技术方面的研究进展。1.3研究方法与创新点概述本文采用Python技术栈的设计方法和系统创新点。第2章相关理论与技术总结自主学习系统后端开发的相关理论和技术基础。2.1自主学习系统理论阐述自主学习系统的定义、特征和理论基础。2.2Python后端技术栈介绍DjangoFlask等Python后端框架及其适用场景。2.3数据库技术讨论关系型和非关系型数据库在系统中的应用方案。第3章系统设计与实现详细介绍自主学习系统后端的设计方案和实现过程。3.1系统架构设计提出基于微服务的系统架构设计方案。3.2核心模块设计详细说明用户管理、学习资源管理、进度跟踪等核心模块设计。3.3关键技术实现阐述个性化推荐算法、学习行为分析等关键技术的实现。第4章系统测试与评估对系统进行功能测试和性能评估。4.1测试环境与方法介绍测试环境配置和采用的测试方法。4.2功能测试结果展示各功能模块的测试结果和问题修复情况。4.3性能评估分析分析系统在高并发等场景下的性能表现。第5章结论与展望总结研究成果并提出未来改进方向。5.1研究结论概括系统设计的主要成果和技术创新。5.2未来展望指出系统局限性并提出后续优化方向。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值