jQuery源码解读之addClass()方法分析


Posted in Javascript onFebruary 20, 2015

本文较为详细的分析了jQuery源码解读之addClass()方法。分享给大家供大家参考。具体分析如下:

给jQuery原型对象扩展addClass功能,jQuery.fn就是jQuery.prototype

jQuery.fn.extend({

/*

可以看出这是一个函数名叫addClass的插件方法。

*/

    addClass: function( value ) {

        var classes, elem, cur, clazz, j, finalValue,

            i = 0,

/*

this表示选择器选择的准备添加class的jQuery对象,len是该jQuery对象数组的长度。

*/

            len = this.length,

//在有一个操作数不是布尔值的情况下,&&操作就不一定返回布尔值,此时,它遵循下列规则:

//1.如果第一个操作数不是布尔类型,则返回第二个操作数;

//2.如果第二个操作数不是布尔类型,则只有在第一个操作数的求值结果为true,的情况下才会返回该对象;

//3.如果两个操作数都不是布尔类型,则返回第二个操作数;

//4.如果有一个操作数是null,则返回null;

//5.如果有一个操作数是NaN,则返回NaN;

//6.如果有一个操作数是undefined,则返回undefined 。

//情况1:如果value是null,符合规则4,返回null,即proceed值为null;

//情况2:如果value是undefine,符合规则6,返回undefined,即proceed值为undefined;

//情况3:如果value是NaN,符合规则5,返回NaN,即proceed值为NaN;

//情况4:如果value是数字类型,返回false;

//情况5:如果value是布尔类型,返回false;

//情况7:如果value是Array,Object,Function类型,符合规则2,但typeof value === 'string'是false,所以返回该对象,返回false。

//情况8:如果value是字符串类型,符合规则2,返回value。

//因此,这句只能判断value是不是字符串类型,并且返回这个字符串赋值给proceed。其他任何类型最后都返回false,或是可被隐式转换为false的类型。

            proceed = typeof value === "string" && value;

//由于上面只能判断是否是字符串类型,下面这句是判断value是否为Function类型。使用了jQuery的全局函数isFunction判断,就是$.isFunction()。

        if ( jQuery.isFunction( value ) ) {

//如果value是Function类型,进到这里了。

//返回jQuery对象,为了链式调用。

//这里的this是你选择器选择的jQuery对象。

            return this.each(function( j ) {

//开始迭代,这里的this可不是jQuery对象了,是当前迭代的DOM对象,所以用jQuery(this)包装了一下,成为一个jQuery对象,这样就可以使用jQuery方法。j表示每次遍历的索引。传递一个用来设置类名的有返回值的value函数。value这个函数每次call当前DOM为其执行对象,并传入当前DOM索引值和类名,value函数返回的值,由jQuery(this).addClass(返回值)再次调用addClass()方法。如果返回的是字符串,就执行另外一个if的分支。如果返回的还是function,则继续调用返回的这个function。

                jQuery( this ).addClass( value.call( this, j, this.className ) );

            });

        }

//之前得到proceed是字符串,这里判断下是否为空字符串,非空字符串隐式转换为true。空字符串隐式转换为false哦,那么if语句块就不再执行了,程序跳到最后的return this,返回这个jQuery对象就执行完了。

        if ( proceed ) {

//proceed非空字符串,开始执行if语句块。假定value是"show bd1"。

//rnotwhite是正则表达式(/\S+/g),意思是全局匹配非空白字符一次或更多次。

//(value || "")返回"show bd1",很简单。

//"show bd1".match((/\S+/g)) || []返回["show", "bd1"],match不知道什么作用的同学快去查查吧。

            classes = ( value || "" ).match( rnotwhite ) || [];

//现在classes是['show', 'bd1']一个你要添加类名的数组。

//下面开始遍历,为每一个DOM对象添加类。

            for ( ; i < len; i++ ) {

//this是jQuery对象,elem是当前DOM对象。

                elem = this[ i ];

/*

===操作符比&&操作符优先级高,先判断DOM节点类型是否是元素节点。

rclass是正则表达式/[\t\r\n\f]/g;

括号内的三目运算符表示,当前DOM节点是否已经有class,有的话,则将class中可能存在的制表符,换行符,回车符等替换为带有一个空格的字符串" ",并且给当前class的前后各加一个空格;如果当前DOM节点还没有class,则也是给一个带一个空格的字符串" "。最后变成

cur = elem.nodeType === 1 && "show bd1",这个很熟悉啊,没错,根据最开始的那6个规则求值。

假定elem的节点类型是1,那么 cur = true && " ",最后cur = "show bd1"。

如果elem的节点类型不是1,那么 cur = false && " ",最后cur = false。

*/

                cur = elem.nodeType === 1 && ( elem.className ?

                    ( " " + elem.className + " " ).replace( rclass, " " ):" ");

//现在cur = " show bd1 ",进入if语句块执行。

                if ( cur ) {

                    j = 0;

/*

classes为["show bd1"]

循环检查要添加的类是否已经存在与当前DOM元素已经有的类里。

如果没有,则添加这个类。

*/

                    while ( (clazz = classes[j++]) ) {

                        if ( cur.indexOf( " " + clazz + " " ) < 0 ) {

                            cur += clazz + " ";

                        }

                    }

/*

最后用$.trim()将类" show bd1 "两头的空格字符去掉。

检查当前DOM元素的类是否和拼接好的类重复。避免不必要的重复添加相同类的渲染。

*/

                    finalValue = jQuery.trim( cur );

                    if ( elem.className !== finalValue ) {

                        elem.className = finalValue;

                    }

                }

            }

        }

//返回这个jQuery对象,为了以后的链式调用。
        return this;

    }

});

希望本文所述对大家的jQuery程序设计有所帮助。

Javascript 相关文章推荐
onpropertypchange
Jul 01 Javascript
brook javascript框架介绍
Oct 10 Javascript
解决jquery的datepicker的本地化以及Today问题
May 23 Javascript
jQuery实现返回顶部效果的方法
May 29 Javascript
C++中的string类的用法小结
Aug 07 Javascript
jQuery实现列表内容的动态载入特效
Aug 08 Javascript
利用Js+Css实现折纸动态导航效果实例源码
Jan 25 Javascript
AngularJS自定义指令实现面包屑功能完整实例
May 17 Javascript
vux uploader 图片上传组件的安装使用方法
May 15 Javascript
Angular使用ControlValueAccessor创建自定义表单控件
Mar 08 Javascript
Vue请求java服务端并返回数据代码实例
Nov 28 Javascript
vue实践---vue不依赖外部资源实现简单多语操作
Sep 21 Javascript
jQuery源码解读之hasClass()方法分析
Feb 20 #Javascript
jQuery源码解读之removeAttr()方法分析
Feb 20 #Javascript
JS实现5秒钟自动封锁div层的方法
Feb 20 #Javascript
js实现感应鼠标图片透明度变化的方法
Feb 20 #Javascript
js实现鼠标感应向下滑动隐藏菜单的方法
Feb 20 #Javascript
js实现鼠标滚轮控制图片缩放效果的方法
Feb 20 #Javascript
IE及IE6浏览器中判断JS文件加载成功失败的方法
Feb 18 #Javascript
You might like
基于PHP的cURL快速入门教程 (小偷采集程序)
2011/06/02 PHP
php5.3 注意事项说明
2013/07/01 PHP
php引用传值实例详解学习
2013/11/06 PHP
php使用wordwrap格式化文本段落的方法
2015/03/17 PHP
解读PHP的Yii框架中请求与响应的处理流程
2016/03/17 PHP
深入理解PHP之OpCode原理详解
2016/06/01 PHP
PHP 等比例缩放图片详解及实例代码
2016/09/18 PHP
PHP实现支付宝即时到账功能
2016/12/21 PHP
我遇到的参数传递中 双引号单引号嵌套问题
2010/02/11 Javascript
基于PHP+Jquery制作的可编辑的表格的代码
2011/04/10 Javascript
artdialog的图片/标题以及关闭按钮不显示的解决方法
2013/06/27 Javascript
原生javaScript做得动态表格(注释写的很清楚)
2013/12/29 Javascript
基于Jquery实现焦点图淡出淡入效果
2015/11/30 Javascript
Javascript的无new构建实例详解
2016/05/15 Javascript
jQuery 翻页组件yunm.pager.js实现div局部刷新的思路
2016/08/11 Javascript
详解vue之页面缓存问题(基于2.0)
2017/01/10 Javascript
在 Typescript 中使用可被复用的 Vue Mixin功能
2018/04/17 Javascript
详解Angular Forms中自定义ngModel绑定值的方式
2018/12/10 Javascript
解决Echarts2竖直datazoom滑动后显示数据不全的问题
2020/07/20 Javascript
vue 子组件watch监听不到prop的解决
2020/08/09 Javascript
[02:08]2014DOTA2国际邀请赛 430专访:力争取得小组前二
2014/07/11 DOTA
python异步任务队列示例
2014/04/01 Python
python实现的简单文本类游戏实例
2015/04/28 Python
总结Python编程中三条常用的技巧
2015/05/11 Python
Python cookbook(数据结构与算法)保存最后N个元素的方法
2018/02/13 Python
对python 匹配字符串开头和结尾的方法详解
2018/10/27 Python
python爬虫分布式获取数据的实例方法
2020/11/26 Python
SOA的常见陷阱或者误解是什么
2014/10/05 面试题
外语系毕业生求职自荐信
2014/04/12 职场文书
客运企业隐患排查工作方案
2014/06/06 职场文书
中国在我心中演讲稿
2014/09/13 职场文书
如何签定毕业生就业协议书
2014/09/28 职场文书
Python自动化爬取天眼查数据的实现
2021/06/15 Python
C#连接ORACLE出现乱码问题的解决方法
2021/10/05 Oracle
vue如何实现关闭对话框后刷新列表
2022/04/08 Vue.js
JS实现简单九宫格抽奖
2022/06/28 Javascript