jQuery源码阅读笔记(8)

CSS类

类名操作提供了四种方式

  • hasClass(className) – 检查是否有一个类

  • addClass(className|fn) – 添加类

  • removeClass(className|fn) – 移除类

  • toggleClass(className|fn[,sw]) – 切换类

对于类名的处理,其实就是正则的玩法了

不过这里并不考虑兼容性问题,有更简便的对象属性,classList

有这么几个的方法

  • contains(className)

  • add(className)

  • remove(className)

  • toggle(className)

对此,只需要做一个简单的包装就好了

hasClass(className)
  • 概述:检查元素是否含义某个类名,只接受一个参数

  • 解析:

    • 一个参数其实就是一个类名,多个使用空格隔开的类名那是不搭理的,都当作一个处理,自己一个一个放
    • 还有一点表现是,只要匹配的元素有一个含有指定类,那么就是true,而非需要全部匹配元素都含有
  • 实现:

    hasClass(className) {
        //不管是个啥,转换为字符串
        className += "";
        //因为是原生属性,且需要返回值立刻退出,就不能使用each循环了
        for (let i = 0; i < this.length; i++) {
            if (this[i].classList.contains(className.trim())) {
                return true;
            }
        }
        return false;
    }
    
addClass(className|fn)
  • 概述:添加类,多个类使用空格隔开

  • 解析:

    • 参数只关注函数和字符串,函数返回值按同理处理
    • 可以接受多个类名,准备一个正则分割,遍历加入其中即可
    • 需要注意,classList.add()可以接受多个参数,对于已含有的类名则不会再次添加
  • 实现:

    addClass(className) {
      //如果是函数
      if (isFunction(className)) {
        return this.each(function(index) {
          $(this).addClass(className.call(this, index, this.className));
        });
      } else if (isString(className)) {
        //将字符串去空格,然后按中间的空格分割
        const arr = className.trim().split(/\s+/);
        return this.each(function() {
          this.classList.add(...arr);
        });
      }
      //此处用于不合适参数的返回值
      return this;
    }
    
removeClass(className|fn)
  • 概述:移除指定类,如果没有参数,则将类全部清空

  • 解析:

    • 与上者同理,只是多加一条判断
  • 实现:

    removeClass(className) {
      if (!arguments.length) {
        return this.each(function() {
          this.className = "";
        });
      } else if (isFunction(className)) {
        return this.each(function(index) {
          //此处可以直接放入没问题,传入一个undefined和没有参数是两回事
          $(this).removeClass(className.call(this, index, this.className));
        });
      } else if (isString(className)) {
        const arr = className.trim().split(/\s+/);
        return this.each(function() {
          this.classList.remove(...arr);
        });
      }
      return this;
    }
    
toggleClass(className|fn[,sw])
  • 概述:根据所拥有的情况,决定是移除还是增加

  • 解析:

    • 第二参数为布尔值,决定了不管拥有或者没有,都移除或者增加
    • 对于这一点挺无聊的,那和直接调用前两个参数没有什么差别
    • 官方版本事实上有一个神奇的表现,那就是来两次切换,第一次可以全部清除,可第二次又可以把所有移除的类又给加回来
    • 对于这个杂技,此处并没有去实现
  • 实现:

    toggleClass(className, stateVal) {
        //没有参数直接清空,且不带回退
        if (className === undefined) {
            return this.each(function() {
                this.className = "";
            });
        }
        //对于函数,依然按照规矩处理
        else if (isFunction(className)) {
            return this.each(function(index) {
                $(this).toggleClass(className.call(this, index, this.className), stateVal);
            });
        }
        //处理字符串,需要查看有没有第二参数存在
        else if (isString(className)) {
            switch (stateVal) {
                case true:
                    return this.addClass(className);
                case false:
                    return this.removeClass(className);
                default:
                    //多个字符串一起处理,先切割
                    const arr = className.trim().split(/\s+/);
                    return this.each(function() {
                        for (let i = 0; i < arr.length; i++) {
                            const target = arr[i];
                            if (this.classList.contains(target)) {
                                this.classList.remove(target);
                            } else {
                                this.classList.add(target);
                            }
                        }
                    });
            }
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值