jQuery attributes(下)

系统 1894 0

前文 对属性的设置、读取、删除方法做了分解,本文继续对jQuery attributes模块分解。

 

jQuery.fn.addClass

      
        /*
      
      
        ***********************************
 *    value: 字符串或者是函数,字符串可以通过空格分隔className
 
      
      
        */
      
      
        
jQuery.fn.addClass 
      
      = 
      
        function
      
      
        ( value ) {
    
      
      
        var
      
      
         classes, elem, cur, clazz, j,
        i 
      
      = 0
      
        ,
        len 
      
      = 
      
        this
      
      
        .length,
        proceed 
      
      = 
      
        typeof
      
       value === "string" &&
      
         value;

    
      
      
        //
      
      
        如果value是函数
      
      
        if
      
      
         ( jQuery.isFunction( value ) ) {
        
      
      
        //
      
      
        则对所有元素迭代运行addClass
      
      
        return
      
      
        this
      
      .each(
      
        function
      
      
        ( j ) {
            jQuery( 
      
      
        this
      
       ).addClass( value.call( 
      
        this
      
      , j, 
      
        this
      
      
        .className ) );
        });
    }

    
      
      
        //
      
      
        如果value是字符串
      
      
        if
      
      
         ( proceed ) {
        
      
      
        //
      
      
         对value字符串分割成数组
      
      
        classes = ( value || "" ).match( core_rnotwhite ) ||
      
         [];

        
      
      
        //
      
      
        遍历元素
      
      
        for
      
       ( ; i < len; i++
      
         ) {
            elem 
      
      = 
      
        this
      
      
        [ i ];
            
      
      
        //
      
      
        如果节点是元素,则获取原来的className
      
      
            cur = elem.nodeType === 1 && ( elem.className ?
      
        
                ( 
      
      " " + elem.className + " " ).replace( rclass, " " ) :    
      
        //
      
      
        替换掉换行符制表符等
      
      
                " "
      
        
            );

            
      
      
        //
      
      
        如果cur不为false,即节点是元素
      
      
        if
      
      
         ( cur ) {
                j 
      
      = 0
      
        ;
                
      
      
        //
      
      
        遍历classes组装成新的className应有的值
      
      
        while
      
       ( (clazz = classes[j++
      
        ]) ) {
                    
      
      
        if
      
       ( cur.indexOf( " " + clazz + " " ) < 0
      
         ) {
                        cur 
      
      += clazz + " "
      
        ;
                    }
                }
                
      
      
        //
      
      
        对className赋值,去掉头尾空白
      
      
                elem.className =
      
         jQuery.trim( cur );

            }
        }
    }

    
      
      
        return
      
      
        this
      
      
        ;
};
      
    

添加class的实现上还是比较简单的,利用elem.className来赋值。需要注意:

        
          var
        
         rclass = /[\t\r\n]/g;
      

 

jQuery.fn.removeClass

      jQuery.fn.removeClass = 
      
        function
      
      
        ( value ) {
    
      
      
        var
      
      
         classes, elem, cur, clazz, j,
        i 
      
      = 0
      
        ,
        len 
      
      = 
      
        this
      
      
        .length,
        
      
      
        //
      
      
        参数是否正确
      
      
        proceed = arguments.length === 0 || 
      
        typeof
      
       value === "string" &&
      
         value;

    
      
      
        //
      
      
        如果value是函数
      
      
        if
      
      
         ( jQuery.isFunction( value ) ) {
        
      
      
        //
      
      
        则对所有元素迭代运行removeClass
      
      
        return
      
      
        this
      
      .each(
      
        function
      
      
        ( j ) {
            jQuery( 
      
      
        this
      
       ).removeClass( value.call( 
      
        this
      
      , j, 
      
        this
      
      
        .className ) );
        });
    }
    
    
      
      
        //
      
      
        如果参数正确
      
      
        if
      
      
         ( proceed ) {
        
      
      
        //
      
      
        分隔value成为class字符串数组
      
      
        classes = ( value || "" ).match( core_rnotwhite ) ||
      
         [];

        
      
      
        //
      
      
        遍历
      
      
        for
      
       ( ; i < len; i++
      
         ) {
            elem 
      
      = 
      
        this
      
      
        [ i ];
            
      
      
        //
      
      
         获取className并进行预处理
      
      
            cur = elem.nodeType === 1 && ( elem.className ?
      
        
                ( 
      
      " " + elem.className + " " ).replace( rclass, " "
      
         ) :
                
      
      ""
      
        
            );

            
      
      
        //
      
      
        如果是元素
      
      
        if
      
      
         ( cur ) {
                j 
      
      = 0
      
        ;
                
      
      
        //
      
      
        遍历所有class字符串
      
      
        while
      
       ( (clazz = classes[j++
      
        ]) ) {
                    
      
      
        //
      
      
         寻找是否有对应的字符串
      
      
        while
      
       ( cur.indexOf( " " + clazz + " " ) >= 0
      
         ) {
                        
      
      
        //
      
      
        有则去掉
      
      
                        cur = cur.replace( " " + clazz + " ", " "
      
         );
                    }
                }
                
      
      
        //
      
      
        给className赋值,并去掉头尾空格
      
      
                elem.className = value ? jQuery.trim( cur ) : ""
      
        ;
            }
        }
    }

    
      
      
        return
      
      
        this
      
      
        ;
};
      
    

删除class的实现和addClass非常像,只是通过indexOf和replace来替换掉需要删除的class。

 

jQuery.fn.toggleClass

      jQuery.fn.toggleClass = 
      
        function
      
      
        ( value, stateVal ) {
    
      
      
        var
      
       type = 
      
        typeof
      
      
         value,
        isBool 
      
      = 
      
        typeof
      
       stateVal === "boolean"
      
        ;

    
      
      
        //
      
      
        (⊙o⊙)…不说了,大家懂得
      
      
        if
      
      
         ( jQuery.isFunction( value ) ) {
        
      
      
        return
      
      
        this
      
      .each(
      
        function
      
      
        ( i ) {
            jQuery( 
      
      
        this
      
       ).toggleClass( value.call(
      
        this
      
      , i, 
      
        this
      
      
        .className, stateVal), stateVal );
        });
    }

    
      
      
        //
      
      
        遍历所有元素
      
      
        return
      
      
        this
      
      .each(
      
        function
      
      
        () {
        
      
      
        //
      
      
        如果value是字符串
      
      
        if
      
       ( type === "string"
      
         ) {
            
      
      
        var
      
      
         className,
                i 
      
      = 0
      
        ,
                self 
      
      = jQuery( 
      
        this
      
      
         ),
                state 
      
      =
      
         stateVal,
                
      
      
        //
      
      
        将value转成classNames字符串数组
      
      
                classNames = value.match( core_rnotwhite ) ||
      
         [];

            
      
      
        //
      
      
        遍历
      
      
        while
      
       ( (className = classNames[ i++
      
         ]) ) {
                
      
      
        //
      
      
        stateVal是布尔量,则直接设置为stateVal,否则判断元素是否不存在该className
      
      
                state = isBool ? state : !
      
        self.hasClass( className );
                
      
      
        //
      
      
        如果该className不存在则添加,否则删除
      
      
                self[ state ? "addClass" : "removeClass"
      
         ]( className );
            }

        
      
      
        //
      
      
         如果value的类型是undefined或者boolean
      
      
        } 
      
        else
      
      
        if
      
       ( type === "undefined" || type === "boolean"
      
         ) {
            
      
      
        //
      
      
        如果元素的className存在
      
      
        if
      
       ( 
      
        this
      
      
        .className ) {
                
      
      
        //
      
      
         将其存入缓存
      
      
                jQuery._data( 
      
        this
      
      , "__className__", 
      
        this
      
      
        .className );
            }

            
      
      
        //
      
      
        对className赋值,为空或者缓存中的值
      
      
        this
      
      .className = 
      
        this
      
      .className || value === 
      
        false
      
       ? "" : jQuery._data( 
      
        this
      
      , "__className__" ) || ""
      
        ;
        }
    });
};
      
    

为了实现jQuery.fn.toggleClass还是花了很大功夫的。

缓存的利用使得toggleClass操作更加方便,而不需要记录以前是那些class。

 

jQuery.fn.hasClass

      jQuery.fn.hasClass = 
      
        function
      
      
        ( selector ) {
    
      
      
        var
      
       className = " " + selector + " "
      
        ,
        i 
      
      = 0
      
        ,
        l 
      
      = 
      
        this
      
      
        .length;
    
      
      
        for
      
       ( ; i < l; i++
      
         ) {
        
      
      
        if
      
       ( 
      
        this
      
      [i].nodeType === 1 && (" " + 
      
        this
      
      [i].className + " ").replace(rclass, " ").indexOf( className ) >= 0
      
         ) {
            
      
      
        return
      
      
        true
      
      
        ;
        }
    }

    
      
      
        return
      
      
        false
      
      
        ;
};
      
    

这个函数通过indexOf来寻找className是否存在。

 

jQuery.fn.val

      jQuery.fn.val = 
      
        function
      
      
        ( value ) {
    
      
      
        var
      
      
         hooks, ret, isFunction,
        elem 
      
      = 
      
        this
      
      [0
      
        ];

    
      
      
        //
      
      
        如果没有参数
      
      
        if
      
       ( !
      
        arguments.length ) {
        
      
      
        //
      
      
        如果元素存在
      
      
        if
      
      
         ( elem ) {
            
      
      
        //
      
      
        得到相应的钩子
      
      
            hooks = jQuery.valHooks[ elem.type ] ||
      
         jQuery.valHooks[ elem.nodeName.toLowerCase() ];

            
      
      
        //
      
      
        通过钩子来得到值
      
      
        if
      
       ( hooks && "get" 
      
        in
      
       hooks && (ret = hooks.get( elem, "value" )) !==
      
         undefined ) {
                
      
      
        return
      
      
         ret;
            }

            
      
      
        //
      
      
        如果没得到钩子,则通过elem.value来返回值
      
      
            ret =
      
         elem.value;

            
      
      
        //
      
      
        如果ret是字符串
      
      
        return
      
      
        typeof
      
       ret === "string" ?
                
      
        //
      
      
         将回车符替换
      
      
                ret.replace(rreturn, ""
      
        ) :
                
      
      
        //
      
      
         如果ret是空的,则返回"",否则返回ret
      
      
                ret == 
      
        null
      
       ? ""
      
         : ret;
        }

        
      
      
        return
      
      
        ;
    }

    
      
      
        //
      
      
        value是否是函数
      
      
    isFunction =
      
         jQuery.isFunction( value );

    
      
      
        //
      
      
        遍历所有元素
      
      
        return
      
      
        this
      
      .each(
      
        function
      
      
        ( i ) {
        
      
      
        var
      
      
         val,
            self 
      
      = jQuery(
      
        this
      
      
        );

        
      
      
        if
      
       ( 
      
        this
      
      .nodeType !== 1
      
         ) {
            
      
      
        return
      
      
        ;
        }

        
      
      
        //
      
      
        如果value是函数,则转成参数
      
      
        if
      
      
         ( isFunction ) {
            val 
      
      = value.call( 
      
        this
      
      
        , i, self.val() );
        } 
      
      
        else
      
      
         {
            val 
      
      =
      
         value;
        }

        
      
      
        //
      
      
         将null/undefined当成""
      
      
        if
      
       ( val == 
      
        null
      
      
         ) {
            val 
      
      = ""
      
        ;
        
      
      
        //
      
      
         将数字转成字符串
      
      
        } 
      
        else
      
      
        if
      
       ( 
      
        typeof
      
       val === "number"
      
         ) {
            val 
      
      += ""
      
        ;
        
      
      
        //
      
      
        如果是数组,则遍历数组
      
      
        } 
      
        else
      
      
        if
      
      
         ( jQuery.isArray( val ) ) {
            val 
      
      = jQuery.map(val, 
      
        function
      
      
         ( value ) {
                
      
      
        return
      
       value == 
      
        null
      
       ? "" : value + ""
      
        ;
            });
        }

        
      
      
        //
      
      
        获取相应钩子
      
      
        hooks = jQuery.valHooks[ 
      
        this
      
      .type ] || jQuery.valHooks[ 
      
        this
      
      
        .nodeName.toLowerCase() ];

        
      
      
        //
      
      
         如果钩子无法设置,则使用通常的设置方法
      
      
        if
      
       ( !hooks || !("set" 
      
        in
      
       hooks) || hooks.set( 
      
        this
      
      , val, "value" ) ===
      
         undefined ) {
            
      
      
        this
      
      .value =
      
         val;
        }
    });
};
      
    

jQuery attributes(下)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论