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 相关文章推荐
实现连缀调用的map方法(prototype)
Aug 05 Javascript
Jquery 过滤器(first,last,not,even,odd)的使用
Jan 22 Javascript
一波JavaScript日期判断脚本分享
Mar 06 Javascript
JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍
May 19 Javascript
jQuery实现ajax的叠加和停止(终止ajax请求)
Aug 08 Javascript
更靠谱的H5横竖屏检测方法(js代码)
Sep 13 Javascript
整理一下常见的IE错误
Nov 18 Javascript
原生js实现鼠标跟随效果
Feb 28 Javascript
Bootstrap 模态对话框只加载一次 remote 数据的完美解决办法
Jul 09 Javascript
jQuery 实现批量提交表格多行数据的方法
Aug 09 jQuery
JS实现图片切换效果
Nov 17 Javascript
CKEditor 4.4.1 添加代码高亮显示插件功能教程【使用官方推荐Code Snippet插件】
Jun 14 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
ThinkPHP之A方法实例讲解
2014/06/20 PHP
PHP实现递归复制整个文件夹的类实例
2015/08/03 PHP
PHP微信企业号开发之回调模式开启与用法示例
2017/11/25 PHP
JavaScript DOM学习第四章 getElementByTagNames
2010/02/19 Javascript
Javascript限制网页只能在微信内置浏览器中访问
2014/11/09 Javascript
JavaScript数据库TaffyDB用法实例分析
2015/07/27 Javascript
jQuery实现带动画效果的多级下拉菜单代码
2015/09/08 Javascript
谈谈encodeURI和encodeURIComponent以及escape的区别与应用
2015/11/24 Javascript
AngularJS入门教程之多视图切换用法示例
2016/11/02 Javascript
详解nodejs操作mongodb数据库封装DB类
2017/04/10 NodeJs
jQuery选择器之子元素过滤选择器
2017/09/28 jQuery
vue弹窗组件的实现示例代码
2018/09/10 Javascript
使用RN Animated做一个“添加购物车”动画的方法
2018/09/12 Javascript
详解微信小程序的不同函数调用的几种方法
2019/05/08 Javascript
[37:21]完美世界DOTA2联赛PWL S2 Inki vs Magma 第二场 11.22
2020/11/24 DOTA
python列表操作使用示例分享
2014/02/21 Python
python应用程序在windows下不出现cmd窗口的办法
2014/05/29 Python
用Python的Flask框架结合MySQL写一个内存监控程序
2015/11/07 Python
Python 文件管理实例详解
2015/11/10 Python
Python使用time模块实现指定时间触发器示例
2017/05/18 Python
解决安装tensorflow遇到无法卸载numpy 1.8.0rc1的问题
2018/06/13 Python
Python3多目标赋值及共享引用注意事项
2019/05/27 Python
Python跳出多重循环的方法示例
2019/07/03 Python
Python遍历字典方式就实例详解
2019/12/28 Python
使用CSS3的rem属性制作响应式页面布局的要点解析
2016/05/24 HTML / CSS
移动端开发HTML5页面点击按钮后出现闪烁或黑色背景的解决办法
2018/09/19 HTML / CSS
华为俄罗斯官方网上商城:购买Huawei手机和平板
2017/04/21 全球购物
台湾线上百货零售购物平台:friDay购物
2017/08/18 全球购物
财务人员担保书
2014/05/13 职场文书
公司周年庆典标语
2014/10/07 职场文书
2014年心理健康教育工作总结
2014/12/06 职场文书
感恩节寄语2015
2015/03/24 职场文书
2019XX公司员工考核管理制度!
2019/08/07 职场文书
MySQL中使用or、in与union all在查询命令下的效率对比
2021/05/26 MySQL
java设计模式--建造者模式详解
2021/07/21 Java/Android
教你一步步实现一个简易promise
2021/11/02 Javascript