jQuery.fn.toggleClass

elem.toggleClass(value,stateVal)

  • 2个实参,第一个是字符串,第二个是 布尔值
    • 第二个参数为true ,添加class value,
    • 第二个参数为false,删除class value
  • 第一个参数是函数
    • 遍历elem中 的每个dom元素执行回调函数,回调函数的this值指向dom元素,第一个参数是dom元素的下标,第二个参数为元素当前的class,第三个参数为toggleClass的第二个参数,然后吧回调函数的返回值作为toggleClass的第一个参数重新执行toggleClass方法
  • 只有一个参数
    • 类型为string ,如果已经存在这个class,则删除,如不过不存在,则添加
    • 值为 false 清空class
  • 没有参数
    • 如果有class,把class缓存起来并清除class
    • 如果没有cass,吧缓存的class添加回去
jQuery.fn.extend({
    toggleClass: function( value, stateVal ) {
        var type = typeof value;
        // 获取第一个参数的数据类型

        if ( typeof stateVal === "boolean" && type === "string" ) {
            // 第一个参数是个字符串并且第二个参数是布尔值
            return stateVal ? this.addClass( value ) : this.removeClass( value );
            //当第二个参数为true时,把value作为className添加进元素
            //当第二个参数为false时,移除元素中的 value class
        }

        //只有一个参数并且是函数
        if ( jQuery.isFunction( value ) ) {
            //第一个参数是函数
            //对当前每个jq对象执行一次函数
            //this指向jq对象数组里的每个元素,i是其下标
            return this.each( function( i ) {
                jQuery( this ).toggleClass(
                    value.call( this, i, getClass( this ), stateVal ),
                    //把i 当前元素的className,stateVal作为参数传递value函数
                    //并把value的this指向当前元素
                    //把返回的值作为第一个参数重新调用函数
                    stateVal
                );
            } );
        }
        //没有参数或只有一个参数是string或boolean
        return this.each( function() {
            var className, i, self, classNames;

            if ( type === "string" ) {
                //第一个参数为字符串类型
                // Toggle individual class names
                i = 0;
                self = jQuery( this );
                classNames = value.match( rnothtmlwhite ) || [];
                ///rnothtmlwhite = ([^\x20\t\r\n\f]+/g)
                //把value根据分隔符拆分成数组,没有匹配到就返回空数组
                while ( ( className = classNames[ i++ ] ) ) {

                    // Check each className given, space separated list
                    if ( self.hasClass( className ) ) {
                        //如果元素有className,则删除
                        self.removeClass( className );
                    } else {
                        //如果没有,则添加
                        self.addClass( className );
                    }
                }

            // Toggle whole class name
            } else if ( value === undefined || type === "boolean" ) {
                //value为undefined或则boolean
                className = getClass( this );
                if ( className ) {
                    //如果元素本来有classname,那么先缓存起来
                    // Store className if set
                    dataPriv.set( this, "__className__", className );
                }

                // If the element has a class name or if we're passed `false`,
                // then remove the whole classname (if there was one, the above saved it).
                // Otherwise bring back whatever was previously saved (if anything),
                // falling back to the empty string if nothing was stored.
                if ( this.setAttribute ) {
                    //元素存在setAttribute方法
                    this.setAttribute( "class",
                        className || value === false ?
                        "" :
                        dataPriv.get( this, "__className__" ) || ""
                        //className有值 或value === false 删除所有classname
                        // 
                    );
                }
            }
        } );
    },
    each: function( callback ) {
        return jQuery.each( this, callback );
    },    
})


jQuery.extend({
        //遍历对象的每个元素,执行回调函数,回调函数的this指向对象成员
        each: function( obj, callback ) {
            var length, i = 0;
            //判断obj是否是类数组对象,比如元素的jq对象
            if ( isArrayLike( obj ) ) {
                length = obj.length;
                for ( ; i < length; i++ ) {
                    //遍历obj对象,执行回调函数
                    if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
                        break;
                    }
                }
            } else {
                for ( i in obj ) {
                    //遍历obj对象,执行回调函数
                    if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
                        break;
                    }
                }
            }

            return obj;
        }
    })
//判断是否为类数组对象
function isArrayLike( obj ) {
    var length = !!obj && "length" in obj && obj.length,
        //length=obj.length,如果不存在,就=false
        type = jQuery.type( obj );

    if ( type === "function" || jQuery.isWindow( obj ) ) {
        return false;
        //如果obj是function或window对象,返回false
    }

    return type === "array" || length === 0 ||
        typeof length === "number" && length > 0 && ( length - 1 ) in obj;
     //如果obj是个数组类型,返回true
     //length存在并且等于0,返回true
     //length存在并且是数值类型而且大于0,obj存在length - 1元素,返回true
     //如果上面所有条件都不满足,返回false,不是个类数组对象
}

你可能感兴趣的:(jQuery.fn.toggleClass)