摘要:形如源代码在的原型上添加了相关方法。类似源代码每个表单的和都通过编码最后通过符号分割有了的基础,就是将相应的和都通过编码,然后用符号进行分割,也就达到了我们要的结果。
前言
JavaScript最初的一个应用场景就是分担服务器处理表单的责任,打破处处依赖服务器的局面,这篇文章主要介绍zepto中form模块关于表单处理的几个方法,serialize、serializeArray、submit。
原文链接
github项目地址
表单相关回顾在开始学些form模块相关方法前,我们先来回顾一下表单提交时,浏览器是怎么样将数据发送给服务器的(以下内容摘自《JavaScript高级程序设计》第14章 14.4节 表单序列化)
对表单字段的名称和值进行URL编码,使用&分隔。
不发送禁用的表单字段。(也就是属性disabled为true的)
只发送勾选的复选框和单选按钮
不发送type为reset和button的按钮
多选选择框中每个选择的值多带带一个条目
在单击提交按钮表单的情况下,也会发送提交按钮的value值,否则不发送提交按钮。
select元素的值,就是选中的option元素的value属性的值,如果option元素没有value属性,则是option元素的文本值。 在表单序列化得过程中,一般不包含任何按钮字段,因为结果字符串很可能是通过其他方式提交的,除此之外其他规则都应该遵循。
有了上面的知识的回顾,接下来我们开始看zepto中serialize和serializeArray的实现
serializeArray因为serialize依赖serializeArray的实现,所以我们先来看看它是怎么实现的。而他的作用是把form表单序列化成一个由 name 和 value 属性组成的对象的数组。形如:
[ {name: "qianlongo", value: "haha"}, {name: "wangmin", value: "heihei"} ]
源代码
$.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),再接着就是判断符合提交到服务器端的表单控件条件了。
需要有name属性(条件为"真")
不能是fieldset元素
不能是已经禁止的元素(即disable为true)
不能是submit、reset、button、file等元素
对于单选和多选控件,只发送已经勾选的。
在上面的条件都满足的条件下,调用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) } }serialize
将表单内容序列化为查询字符串。类似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事件添加一个回调处理函数。
如果没有传入回调函数则触发当前表单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源码分析之form模块
zepto模块
这些Zepto中实用的方法集
Zepto核心模块之工具方法拾遗
event模块
mouseenter与mouseover为何这般纠缠不清?
向zepto.js学习如何手动触发DOM事件
谁说你只是"会用"jQuery?
ajax模块
原来你是这样的jsonp(原理与具体实现细节)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/88819.html
摘要:模块处理的是表单提交。表单提交包含两部分,一部分是格式化表单数据,另一部分是触发事件,提交表单。最终返回的结果是一个数组,每个数组项为包含和属性的对象。否则手动绑定事件,如果没有阻止浏览器的默认事件,则在第一个表单上触发,提交表单。 Form 模块处理的是表单提交。表单提交包含两部分,一部分是格式化表单数据,另一部分是触发 submit 事件,提交表单。 读 Zepto 源码系列文章已...
摘要:的模块用来获取节点中的属性的数据,和储存跟相关的数据。获取节点指定的缓存值。如果存在,则删除指定的数据,否则将缓存的数据全部删除。为所有下级节点,如果为方法,则节点自身也是要被移除的,所以需要将自身也加入到节点中。 Zepto 的 Data 模块用来获取 DOM 节点中的 data-* 属性的数据,和储存跟 DOM 相关的数据。 读 Zepto 源码系列文章已经放到了github上,欢...
摘要:还有一点需要注意的是方法设置或者获取都是在操作元素的属性,那它和,的区别在哪呢可以查看设置设置与的设置部分比较类似,既支持直接传入普通的字符串也支持传入回调函数。 前言 使用Zepto的时候,我们经常会要去操作一些DOM的属性,或元素本身的固有属性或自定义属性等。比如常见的有attr(),removeAttr(),prop(),removeProp(),data()等。接下来我们挨个整...
阅读 2067·2021-11-24 09:39
阅读 773·2021-09-30 09:48
阅读 974·2021-09-22 15:29
阅读 2409·2019-08-30 14:17
阅读 1884·2019-08-30 13:50
阅读 1336·2019-08-30 13:47
阅读 977·2019-08-30 13:19
阅读 3416·2019-08-29 16:43