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 相关文章推荐
利用onresize使得div可以随着屏幕大小而自适应的代码
Jan 15 Javascript
DIY jquery plugin - tabs标签切换实现代码
Dec 11 Javascript
DOM_window对象属性之--clipboardData对象操作代码
Feb 03 Javascript
javascript学习笔记(四) Number 数字类型
Jun 19 Javascript
引用外部脚本时script标签关闭的写法
Jan 20 Javascript
jquery序列化表单去除指定元素示例代码
Apr 10 Javascript
jQuery实现统计输入文字个数的方法
Mar 11 Javascript
javascript:void(0)点击登录没反应怎么解决
Nov 13 Javascript
跟我学习javascript的隐式强制转换
Nov 16 Javascript
JavaScript类型系统之Object详解
Jan 07 Javascript
javascript遍历json对象的key和任意js对象属性实例
Mar 09 Javascript
React Native使用fetch实现图片上传的示例代码
Mar 07 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编程最快明白》第五讲:php目录、文件操作
2010/11/01 PHP
php curl 登录163邮箱并抓取邮箱好友列表的代码(经测试)
2011/04/07 PHP
用Zend Studio+PHPnow+Zend Debugger搭建PHP服务器调试环境步骤
2014/01/19 PHP
PHP中文乱码解决方案
2015/03/05 PHP
PHP开发之用微信远程遥控服务器
2018/01/25 PHP
dojo随手记 gird组件引用
2011/02/24 Javascript
jquery关于事件冒泡和事件委托的技巧及阻止与允许事件冒泡的三种实现方法
2015/11/27 Javascript
JS验证 只能输入小数点,数字,负数的实现方法
2016/10/07 Javascript
JavaScript实现二维坐标点排序效果
2017/07/18 Javascript
webpack踩坑之路图片的路径与打包
2017/09/05 Javascript
关于vue-router的那些事儿
2018/05/23 Javascript
详解适配器在JavaScript中的体现
2018/09/28 Javascript
js 数据类型判断的方法
2020/12/03 Javascript
[03:04]DOTA2英雄基础教程 影魔
2013/12/11 DOTA
[47:38]Optic vs VGJ.S 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
python 查找文件夹下所有文件 实现代码
2009/07/01 Python
Tornado Web服务器多进程启动的2个方法
2014/08/04 Python
Python中filter与lambda的结合使用详解
2019/12/24 Python
python matplotlib 绘图 和 dpi对应关系详解
2020/03/14 Python
中外合拍动画首获奥斯卡提名,“上海出品”《飞奔去月球》能否拿下最终大奖?
2021/03/16 国漫
HTML5触摸事件(touchstart、touchmove和touchend)的实现
2020/05/08 HTML / CSS
html table呈现个人简历以及单元格宽度失效的问题解决
2021/01/22 HTML / CSS
孕妇装中的著名品牌:Isabella Oliver(伊莎贝拉·奥利弗)
2016/10/31 全球购物
世界上最具创新性的增强型知名运动品牌:Proviz
2018/04/03 全球购物
泰国综合购物网站:Lazada泰国
2018/04/09 全球购物
韩国保养品、日本药妆购物网:小三美日
2018/12/30 全球购物
Jones New York官网:美国女装品牌,受白领女性欢迎
2019/11/26 全球购物
军校制空专业毕业生自我鉴定
2013/11/16 职场文书
财会自我鉴定范文
2013/12/27 职场文书
会计员岗位职责
2014/03/15 职场文书
《英英学古诗》教学反思
2014/04/11 职场文书
公司贷款承诺书
2014/05/30 职场文书
2014党员批评和自我批评思想汇报
2014/09/21 职场文书
三八妇女节寄语
2015/02/27 职场文书
python opencv旋转图片的使用方法
2021/06/04 Python
Apache SeaTunnel实现 非CDC数据抽取
2022/05/20 Servers