jQuery从入门到精通源码分析系列(二十八) 样式操作 – addClass
沉沙 2018-07-24 来源 : 阅读 1051 评论 0

摘要:本篇jQuery教程探讨了样式操作addClass的相关内容,希望阅读本篇文章以后大家有所收获,帮助大家对jQuery的理解更加深入。

根据API分类

CSS

· addClass()

· jQuery.cssHooks

· .hasClass()

· .removeClass()

· .toggleClass()

.addClass()

对元素的样式操作,底层的实现就是修改元素的className值

实现的功能:

增加一条样式规则: .addClass(‘myClass’)

增加多条样式规则: .addClass(‘myClass yourClass’)

传递回调遍历样式规则:

$("ul li:last").addClass(function(index) {

  return "item-" + index;

});

从接口传参去分析这个实现手法:

源码:

addClass源码

我把代码简略的分了5个步骤

· 如果传递的是回调函数,递归调用

· 分解下样式规则,通过正则/\S+/g 空白分组

· 如果元素本身存在class样式,先取出来

· 组合成新的规则按照空格分开

· 通过className 设置新的样式 

传递一个参数与多个参数的处理无非就是字符串的拼接,这里就不详讲,看看代码就能理解

重点说一下传递回调函数的设计

官方给的测试案例

HTML结构

<p class ='selected highlight'>Goodbye</p>

<p class ='selected1 highlight1'>Goodbye</p>

<p class ='selected2 highlight2'>Goodbye</p>

增加样式代码

$(p).addClass(function(index,className){//        index  className

//        0 "selected highlight"

//        1 "selected1 highlight1"

//        2 "selected2 highlight2"

    });

遍历出所有的P节点,并找其对应的class,返回给每一个回调函数

看看源码的设计

//如果传递的是回调函数,递归调用  ⑴if ( jQuery.isFunction( value ) ) {

    return this.each(function( j ) {   //each addClass回调 

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

    });

}

不管是写插件还是其他的,只要是设计操作DOM的在jQuery内部就的到 this.each方法

原因很简单,jQuery就是一个数组保存着所有对应的节点的下标

内部在传递一个编写好的回调函数,传递给each方法

each方法理解就是一个循环方法,分解出jQuery数组中每一个下标元,然后把每一个元素返回给外部回调

这里在进步替换下代码就很明显了

function(  i, obj[ i ]  ) {   //each addClass回调

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

 }

这里的this是指向的每一个p元素节点,因为callback.call了一下,把每一个上下文指定到当前的函数了,所以this就是对应的obj[i]

最后执行的代码就是

value.call( this, j, this.className )

value就是最外层用户定义的回调了

$(p).addClass(function(index,className){//        index  className

//        0 "selected highlight"

//        1 "selected1 highlight1"

//        2 "selected2 highlight2"

    });

这里意外的发现jQuery Api没给出

还包装了一层jQuery( this ).addClass

那么意味着,jQuery还可以接受用户最外层的返回参数,然后再调用addClass给当前节点增加新的类名

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

p.addClass(function(index,className){

        return 'aaaa'

    });

.removeClass( [className ] )

代码跟结构与addClass很相似

removeClass源码

.hasClass

.hasClass() 检测匹配的元素是否指定了传入的class,只要有一个匹配就返回true;

元素可能有多个class,在HTML中多个class用空格隔开;

如果遇到某个元素含有指定的className,.hasClass()将会返回true,即便还指定了其他的className。

/**

* 检测匹配的元素是否指定了传入的class,只要有一个匹配就返回true

 * .hasClass( className )

 *   className 要查找的class

* 核心技巧:前后加空格 + indexOf

 */

hasClass: function( selector ) {

    var className = " " + selector + " ", // 前后加空格

        i = 0,

        l = this.length;

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

         // 必须是Element,技巧同样是前后加空格,同样是indexOf

        if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {

            return true;

        }

    }

    return false;

},

jQuery.cssHooks

//www.css88.com/jqapi-1.9/jQuery.cssHooks/

关于jQuery的钩子,单独暴露的一个接口,然用户可以自定义兼容

//www.cnblogs.com/aaronjs/p/3387906.html 文章已经说了原理

.toggleClass()

.toggleClass() 负责对匹配元素集中的每个元素增加或删除一个或多个class,增加或删除的行为依赖当前元素是否含有指定的class或switch参数的值;

.toggleClass()接受一个或多个class;自从jQuery1.4以后,如果没有为.toggleClass()指定参数,元素上的所有class名称将被切换;

自从jQuery1.4以后,className可以是一个函数,函数的返回值作为切换的className。

通过判断节点上是否有className从而实现切换

结合了hasClass,addClass,removeClass

while ( (className = classNames[ i++ ]) ) {

    // check each className given, space separated list

    if ( self.hasClass( className ) ) {

        self.removeClass( className );

    } else {

        self.addClass( className );

    }

}


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标WEB前端jQuery频道!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程