• jQuery源码学习(1)——addClass


      最近比较闲,寻思着学习下jQuery源码,看了好多博客,很多都讲的比较详细。jQuery虽然只有那么200多K,但内容却比较丰富,对于我这样一个js菜鸟,看起来相当吃力。骨头太大,只能化整为零,从简单的小块开始。

        今天看了下class系列的方法,贴下来!可能网上已经有很多,就当做自己记录笔记吧,请勿喷饭!

    //添加类
        addClass: function( value ) {
            var classNames, i, l, elem,
                setClass, c, cl;
            
            //如果value是一个函数,则调用这个函数得到运算结果,然后再递归调用addClass
            if ( jQuery.isFunction( value ) ) {
                return this.each(function( j ) {
                    jQuery( this ).addClass( value.call(this, j, this.className) );
                });
            }
    
            if ( value && typeof value === "string" ) {
                //得到传入的class数组
                classNames = value.split( core_rspace );
    
                //this表示调用此方法的jQuery对象,可能有多个
                for ( i = 0, l = this.length; i < l; i++ ) {
                    elem = this[ i ];
                    //元素类型节点类型:元素element 1;属性attr 2;文本text 3;注释comments 8;文档document 9        
                    //如果是元素节点        
                    if ( elem.nodeType === 1 ) {
                        //如果元素没有class并且classNames数组只有一个元素,则直接赋值
                        if ( !elem.className && classNames.length === 1 ) {
                            elem.className = value;
    
                        } else {
                            setClass = " " + elem.className + " ";
    
                            //循环添加要加入的class
                            for ( c = 0, cl = classNames.length; c < cl; c++ ) {
                                if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) {
                                    setClass += classNames[ c ] + " ";
                                }
                            }
                            elem.className = jQuery.trim( setClass );
                        }
                    }
                }
            }
            //返回获取的jQuery对象
            return this;
        },
    //删除指定的类
        removeClass: function( value ) {
            var removes, className, elem, c, cl, i, l;
    
            if ( jQuery.isFunction( value ) ) {
                return this.each(function( j ) {
                    jQuery( this ).removeClass( value.call(this, j, this.className) );
                });
            }
            if ( (value && typeof value === "string") || value === undefined ) {
                removes = ( value || "" ).split( core_rspace );
    
                for ( i = 0, l = this.length; i < l; i++ ) {
                    elem = this[ i ];
                    if ( elem.nodeType === 1 && elem.className ) {
    
                        //获取当前元素的class(用空格替换制表符或回车符、换行符)
                        className = (" " + elem.className + " ").replace( rclass, " " );
    
                        // loop over each item in the removal list
                        for ( c = 0, cl = removes.length; c < cl; c++ ) {
                            // Remove until there is nothing to remove,
                            while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) {
                                className = className.replace( " " + removes[ c ] + " " , " " );
                            }
                        }
                        //如果value为空,则直接去掉元素的所有class;否则使用处理后的className
                        elem.className = value ? jQuery.trim( className ) : "";
                    }
                }
            }
            //大部分方法都是返回this,遍于进行链式操作
            return this;
        },
    //如果没有class则添加,如果有则删除
        //如果stateVal设置为true,则添加样式;如果为false,则删除样式
        toggleClass: function( value, stateVal ) {
            var type = typeof value,
            //判断stateVal是否为boolean类型
            isBool = typeof stateVal === "boolean";
    
            //value为function时递归调用
            if ( jQuery.isFunction( value ) ) {
                return this.each(function( i ) {
                    jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
                });
            }
    
            return this.each(function() {
                if ( type === "string" ) {
                    // toggle individual class names
                    var className,
                    i = 0,
                    self = jQuery( this ),
                    state = stateVal,
                    classNames = value.split( core_rspace );
                    
                    //如果className[ i++ ] 存在
                    while ( (className = classNames[ i++ ]) ) {
                        // check each className given, space separated list
                        //如果第二个参数是boolean类型,则将第二个参数赋值给state;
                        //否则判断当前jQuery对象是否拥有className这个类,将判断结果取反,赋值给state
                        state = isBool ? state : !self.hasClass( className );
                        //如果state为true,则将className赋值给self['addClass'];
                        //如果state为false,则将className赋值为self['removeClass'],这里的self就是当前jQuery对象
                        self[ state ? "addClass" : "removeClass" ]( className );
                    }
    
                } else if ( type === "undefined" || type === "boolean" ) {
                    if ( this.className ) {
                        // store className if set
                        jQuery._data( this, "__className__", this.className );
                    }
    
                    // toggle whole className
                    //如果className为空或者value为false,则直接清空对象的class;
                    //否则将保存的_className赋值给当前对象的className
                    this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
                }
            });
        },
    //判断某个对象(或一个对象集中的第一个对象)是否拥有某个class
        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;
        },
  • 相关阅读:
    Android API之android.provider.ContactsContract.Data
    Android API之android.provider.ContactsContract
    Android API之android.provider.ContactsContract.Contacts
    Android API之android.os.Parcelable
    Android网络开发之基本介绍
    wpf小技巧——datagrid 滚动条问题
    C# List去重的三种方法(转)
    spring jwt springboot RESTful API认证方式
    Springboot 实现api校验和登录验证
    SpringBoot系列
  • 原文地址:https://www.cnblogs.com/peislin/p/2826371.html
Copyright © 2020-2023  润新知