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实现改变TEXTAREA滚动条和按钮的颜色,以及怎样让滚动条变得扁平
Apr 20 Javascript
仅IE支持clearAttributes/mergeAttributes方法使用介绍
May 04 Javascript
jquery 实现checkbox全选,反选,全不选等功能代码(奇数)
Oct 24 Javascript
jquery动态添加删除(tr/td)
Feb 09 Javascript
javascript每日必学之多态
Feb 23 Javascript
JS组件Bootstrap Select2使用方法解析
May 30 Javascript
canvas实现手机端用来上传用户头像的代码
Oct 20 Javascript
AngularJs 利用百度地图API 定位当前位置 获取地址信息
Jan 18 Javascript
vuex 项目结构目录及一些简单配置介绍
Apr 08 Javascript
详解express使用vue-router的history踩坑
Jun 05 Javascript
webpack4 配置 ssr 环境遇到“document is not defined”
Oct 24 Javascript
介绍一下28个JS常用数组方法
May 06 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
跟我学Laravel之路由
2014/10/15 PHP
详解使用php-cs-fixer格式化代码
2020/09/16 PHP
javascript window.opener的用法分析
2010/04/07 Javascript
javascript中的对象创建 实例附注释
2011/02/08 Javascript
jquery 实现窗口的最大化不论什么情况
2013/09/03 Javascript
JavaScript使用focus()设置焦点失败的解决方法
2014/09/03 Javascript
JS实现文件动态顺序载入的方法
2015/03/07 Javascript
借助FileReader实现将文件编码为Base64后通过AJAX上传
2015/12/24 Javascript
JS获取年月日时分秒的方法分析
2016/11/28 Javascript
JS实现的添加弹出层并完成锁屏操作示例
2017/04/07 Javascript
JavaScript中的遍历详解(多种遍历)
2017/04/07 Javascript
layui前端框架之table表数据的刷新方法
2018/08/17 Javascript
详解jQuery获取特殊属性的值以及设置内容
2018/11/14 jQuery
JS使用对象的defineProperty进行变量监控操作示例
2019/02/02 Javascript
Node.js中package.json中库的版本号(~和^)
2019/04/02 Javascript
实例讲解React 组件生命周期
2020/07/08 Javascript
使用vue实现通过变量动态拼接url
2020/07/22 Javascript
如何使用RoughViz可视化Vue.js中的草绘图表
2021/01/30 Vue.js
Python中使用不同编码读写txt文件详解
2015/05/28 Python
python中Apriori算法实现讲解
2017/12/10 Python
python初学之用户登录的实现过程(实例讲解)
2017/12/23 Python
python cv2读取rtsp实时码流按时生成连续视频文件方式
2019/12/25 Python
html5 浏览器支持 如何让所有的浏览器都支持HTML5标签样式
2012/12/07 HTML / CSS
Blancsom美国/加拿大:服装和生活用品供应商
2018/07/27 全球购物
什么是lambda函数
2013/09/17 面试题
幼儿园教师考核制度
2014/02/01 职场文书
学校先进集体事迹材料
2014/05/31 职场文书
危货运输企业安全生产责任书
2014/07/28 职场文书
践行三严三实心得体会
2014/10/13 职场文书
乡镇民主生活会发言材料
2014/10/20 职场文书
2014年会计工作总结
2014/11/27 职场文书
2014年销售经理工作总结
2014/12/01 职场文书
担保书范本
2015/01/20 职场文书
2015教师节师德演讲稿
2015/03/19 职场文书
导游词之南京莫愁湖公园
2019/11/13 职场文书
在MySQL中你成功的避开了所有索引
2022/04/20 MySQL