今天第一次阅读jQuery源码,因为读到用js对表单的序列化,为的是在ajax操作中将表单中各个域的值传到服务器。书上用了很长的步骤,判断每一个表单域的属性,然后拼接。

大概是这样:

function serialize(form){
var parts = [],
filed = null,
i,
len,
j,
... for(i=0,len=form.elements.length;i<len;i++){
field=form.elements[i];
switch(field.type){
case "select-one":
case "select-multiple":
... }
} }

忽然想到jQuery应该是把这些封装的很好,就找来读了。第一次发现这种语言其实很优美,比Java简洁。

我开始有点喜欢上这门语言了 :)

一般我们是这样调用的

$('#dataform').serialize()

找了版本1.8.2的jQuery源码来读

function () {
return jQuery.param(this.serializeArray());
}

最外层只调用了两个方法.jQuery.param()和jQuery对象本身的serializeArray(),从字面上理解就是

1.将表单本身序列化成数组

2.然后从中获得参数

分解如下:

1.先将表单本身序列化成数组

serializeArray()

 function () {
return this.map(function () {
return this.elements ? jQuery.makeArray(this.elements) : this;
}).filter(function () {
return this.name && !this.disabled && (this.checked || rselectTextarea.test(this.nodeName) || rinput.test(this.type));
}).map(function (i, elem) {
var val = jQuery(this).val(); return val == null ? null : jQuery.isArray(val) ? jQuery.map(val, function (val, i) {
return {
name: elem.name,
value: val.replace(rCRLF, "\r\n")
};
}) : {
name: elem.name,
value: val.replace(rCRLF, "\r\n")
};
}).get();
}

jQuery.map(callback)将一个数组"映射"成另一个数组,对其中每个元素调用callback方法。

接着返回表单中所有元素的数组。

必须有name,disabled为false,勾选上或是type包含在rinput之中。

取得过滤后元素的val,若val非null,再判断val是否是Array,对其中每个元素,返回一个对象,对象的name为元素的name,value为元素的val,并替换其中的制表符。

最后获取其中的数组。

所以这里看来,原先用js做的复杂switch判断都包含在了rselectTextarea.test(this.nodeName) || rinput.test(this.type)中,正则表达式果然强大。

具体就是这两个

/^(?:select|textarea)/i 

/^(?:color|date|datetime|datetimelocal|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i

哈哈,提到正则表达式,顺便给出刚搜到的幽默图片。

女:哦不!杀手肯定在假期里跟踪着她,但是要找到他们,我们必须要在200MB的邮件里找出像地址一类的东西!

男:没希望了!

程序员:众人闪开!我知道正则表达式。看我Perl大法!(啪啪键盘声)

好,现在我们回来继续看源码。

2.从数组中中获得参数

param()

 function (a, traditional) {
var prefix, s = [],
add = function (key, value) {
// If value is a function, invoke it and return its value
value = jQuery.isFunction(value) ? value() : (value == null ? "" : value);
s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
}; // Set traditional to true for jQuery <= 1.3.2 behavior.
if (traditional === undefined) {
traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
} // If an array was passed in, assume that it is an array of form elements.
if (jQuery.isArray(a) || (a.jquery && !jQuery.isPlainObject(a))) {
// Serialize the form elements
jQuery.each(a, function () {
add(this.name, this.value);
}); } else {
// If traditional, encode the "old" way (the way 1.3.2 or older
// did it), otherwise encode params recursively.
for (prefix in a) {
buildParams(prefix, a[prefix], traditional, add);
}
} // Return the resulting serialization
return s.join("&").replace(r20, "+");
}

定义数组s来存放字符串

定义add()来拼接key/value,如果value是方法,则调用,否则返回value值。将key和value编码后放入s

如果a是数组,那么假定a就是表单元素的集合。对其中所有元素调用add()。最后将s中所有字符串用&拼接。

总结:

按代码数来看,jquery写法与原生js的写法相差不多。但在扩展性上要好。

jQuery.fn.serialize 阅读的更多相关文章

  1. 记jQuery.fn.show的一次踩坑和问题排查

    最近很少已经很少用jQuery,因为主攻移动端,常用Zepto,其实很多细节和jQuery并不一样.最近又无意中接触到了PC的需求和IE6, 使用了jQuery,刚好踩坑了,特意记录一下. 本文内容如 ...

  2. jQuery.fn

    DIY一个jQuery 写了一个非常简单的 jQuery.fn.init 方法: jQuery.fn.init = function (selector, context, root) { if (! ...

  3. jQuery.fn的作用是什么

    jQuery.fn的作用是什么:在自定义jQuery插件中,会经常见到jQuery.fn的身影,下面就简单介绍一下它的作用到底是什么.想要认识它的本质,最好的办法直接看jQuery的源码,否则一切都是 ...

  4. 拓展jQuery的serialize(),将form表单转化为json对象

    jQuery 的 serialize() 方法经常会报 Uncaught TypeError: JSON.serializeObject is not a function 的错误, 原装的方法真的一 ...

  5. jQuery 源码学习 - 02 - jQuery.fn.extend 与 jQuery.extend

    参考资料:[深入浅出jQuery]源码浅析--整体架构,备用地址:chokcoco/jQuery-. extend 方法在 jQuery 中是一个很重要的方法.jQuery 内部用它来拓展静态方法或者 ...

  6. jquery.fn.extend与jquery.extend--(初体验二)

    1.jquery.extend(object); 为扩展jQuery类本身.为类添加新的方法. jquery.fn.extend(object);给jQuery对象添加方法. $.extend({ a ...

  7. jQuery为开发插件提拱了两个方法:jQuery.fn.extend(); jQuery.extend();

    jQuery为开发插件提拱了两个方法,分别是: jQuery.fn.extend(); jQuery.extend(); jQuery.fn jQuery.fn = jQuery.prototype ...

  8. jQuery.extend和jQuery.fn.extend的区别【转】

    解释的很有意思,清晰明了又有趣,转来分享下,哈哈哈 jQuery.extend和jQuery.fn.extend的区别,其实从这两个办法本身也就可以看出来.很多地方说的也不详细.这里详细说说之间的区别 ...

  9. ES6的Iterator,jquery Fn

    ES6的Iterator对象详解 Iterator实现原理 创建一个指针对象,指向当前数据结构的起始位置.也就是说,遍历器对象本质上,就是一个指针对象. 第一次调用指针对象的next方法,可以将指针指 ...

随机推荐

  1. vs2012C#编程环境设置智能提示

    vs2012 智能提示和  显示行号的问题 路径为    菜单里 工具-->选项-->文本编辑器-->C#  如图所示 自动列出成员就是 vs里面的智能提示 行号就会显示所写代码的行 ...

  2. BZOJ 2245: [SDOI2011]工作安排( 费用流 )

    费用流模板题..限制一下不同愤怒值的工作数就可以了. ------------------------------------------------------------------------- ...

  3. tengine install

    ./configure --prefix=/home/admin/local/tengine --with-http_stub_status_module --with-http_ssl_module ...

  4. hdu 4612 Warm up 有重边缩点+树的直径

    题目链接 Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Tot ...

  5. 深度探索QT窗口系统(五篇)

    窗口作为界面编程中最重要的部分,没有窗口就没有界面,是窗口让我们摆脱了DOS时代,按钮是一个窗口,文本框是一个窗口,标签页是一个窗口,...一个窗口可以由多个窗口组成,每天我们都在与窗口打交道,当你打 ...

  6. css em

    em与px换算 任意浏览器的默认字体高度16px(16像素).所有未经调整的浏览器都符合: 1em=16px.那么,12px=0.75em,10px=0.625em.为了简化font-size的换算, ...

  7. 使用tcpdump抓Android网络包

    1 抓包原理 tcpdump(需Root用户运行)拦截和显示发送或收到过网络连接到该机器的TCP/IP和其他数据包.简单说就监控手机进出网络数据. 2 方法优劣 2.1优点 1.手机数据包无遗漏 2. ...

  8. rsyslog 不打印日志到/var/log/messages

    *.info;mail.none;authpriv.none;cron.none;local3.none /var/log/messages 表示 所有来源的info级别都记录到/var/log/me ...

  9. Java基础:容器

    转载请注明出处:jiq•钦's technical Blog 一.Collection:存放独立元素 Collection中的接口都是可选操作,事实上现类 并不一定实现了其全部接口,这是为了防止&qu ...

  10. 关于对象和this、new

    //创建一个猫类 function Cat(name,color,eyeColor){ //上面处Cat首字母大写表示创建一个‘类别’叫Cat类.假如首字母小写cat则是创建一个cat的函数: thi ...