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 相关文章推荐
Javascript正则控制文本框只能输入整数或浮点数
Sep 02 Javascript
jquery专业的导航菜单特效代码分享
Aug 29 Javascript
JS根据浏览器窗口大小实时动态改变网页文字大小的方法
Feb 25 Javascript
Vue修改mint-ui默认样式的方法
Feb 03 Javascript
AngularJS修改model值时,显示内容不变的实例
Sep 13 Javascript
js实现动态添加上传文件页面
Oct 22 Javascript
react同构实践之实现自己的同构模板
Mar 13 Javascript
使用element-ui table expand展开行实现手风琴效果
Mar 15 Javascript
微信小程序拼接图片链接无底洞深入探究
Sep 03 Javascript
JS在Array数组中按指定位置删除或添加元素对象方法示例
Nov 19 Javascript
JS+HTML实现自定义上传图片按钮并显示图片功能的方法分析
Feb 12 Javascript
js实现抽奖功能
Nov 24 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
德生PL990,目前市面上唯一一款便携式插卡蓝牙全波段高性能收音机
2021/03/02 无线电
用PHP创建PDF中文文档
2006/10/09 PHP
PHP可逆加密/解密函数分享
2012/09/25 PHP
php截取字符串并保留完整xml标签的函数代码
2013/02/06 PHP
php自定义的格式化时间示例代码
2013/12/05 PHP
php使用递归计算文件夹大小
2014/12/24 PHP
使用phpexcel类实现excel导入mysql数据库功能(实例代码)
2016/05/12 PHP
JavaScript实现删除电脑的关机键
2016/07/26 PHP
Laravel 6 将新增为指定队列任务设置中间件的功能
2019/08/06 PHP
javascript读取xml
2006/11/04 Javascript
jQuery的三种$()
2009/12/30 Javascript
方便实用的jQuery checkbox复选框全选功能简单实例
2013/10/09 Javascript
javascript的渐进增强与平稳退化浅谈
2013/11/12 Javascript
jquery.cookie.js实现用户登录保存密码功能的方法
2016/04/15 Javascript
js实现返回顶部效果
2017/03/10 Javascript
100行代码实现vue表单校验功能(小白自编)
2019/11/19 Javascript
[01:16:28]DOTA2-DPC中国联赛 正赛 iG vs Magma BO3 第二场 2月23日
2021/03/11 DOTA
python杀死一个线程的方法
2015/09/06 Python
Python实现批量修改图片格式和大小的方法【opencv库与PIL库】
2018/12/03 Python
对Python使用mfcc的两种方式详解
2019/01/09 Python
python django框架中使用FastDFS分布式文件系统的安装方法
2019/06/10 Python
如何在mac环境中用python处理protobuf
2019/12/25 Python
python 消除 futureWarning问题的解决
2019/12/25 Python
简单了解django文件下载方式
2020/02/10 Python
python GUI库图形界面开发之PyQt5下拉列表框控件QComboBox详细使用方法与实例
2020/02/27 Python
Python Tkinter实例——模拟掷骰子
2020/10/24 Python
python tkinter的消息框模块(messagebox,simpledialog)
2020/11/07 Python
python解包用法详解
2021/02/17 Python
HTML5 video视频字幕的使用和制作方法
2018/05/03 HTML / CSS
大学生求职自荐信
2013/12/12 职场文书
创文明城市标语
2014/06/16 职场文书
12.4法制宣传日标语
2014/10/08 职场文书
地方课程教学计划
2015/01/19 职场文书
公司承诺书格式范文
2015/04/28 职场文书
Python字典和列表性能之间的比较
2021/06/07 Python
Spring Boot 的创建和运行示例代码详解
2022/07/23 Java/Android