classes.js (4527B)
1 define( [ 2 "../core", 3 "../core/stripAndCollapse", 4 "../var/isFunction", 5 "../var/rnothtmlwhite", 6 "../data/var/dataPriv", 7 "../core/init" 8 ], function( jQuery, stripAndCollapse, isFunction, rnothtmlwhite, dataPriv ) { 9 10 "use strict"; 11 12 function getClass( elem ) { 13 return elem.getAttribute && elem.getAttribute( "class" ) || ""; 14 } 15 16 function classesToArray( value ) { 17 if ( Array.isArray( value ) ) { 18 return value; 19 } 20 if ( typeof value === "string" ) { 21 return value.match( rnothtmlwhite ) || []; 22 } 23 return []; 24 } 25 26 jQuery.fn.extend( { 27 addClass: function( value ) { 28 var classNames, cur, curValue, className, i, finalValue; 29 30 if ( isFunction( value ) ) { 31 return this.each( function( j ) { 32 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 33 } ); 34 } 35 36 classNames = classesToArray( value ); 37 38 if ( classNames.length ) { 39 return this.each( function() { 40 curValue = getClass( this ); 41 cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 42 43 if ( cur ) { 44 for ( i = 0; i < classNames.length; i++ ) { 45 className = classNames[ i ]; 46 if ( cur.indexOf( " " + className + " " ) < 0 ) { 47 cur += className + " "; 48 } 49 } 50 51 // Only assign if different to avoid unneeded rendering. 52 finalValue = stripAndCollapse( cur ); 53 if ( curValue !== finalValue ) { 54 this.setAttribute( "class", finalValue ); 55 } 56 } 57 } ); 58 } 59 60 return this; 61 }, 62 63 removeClass: function( value ) { 64 var classNames, cur, curValue, className, i, finalValue; 65 66 if ( isFunction( value ) ) { 67 return this.each( function( j ) { 68 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 69 } ); 70 } 71 72 if ( !arguments.length ) { 73 return this.attr( "class", "" ); 74 } 75 76 classNames = classesToArray( value ); 77 78 if ( classNames.length ) { 79 return this.each( function() { 80 curValue = getClass( this ); 81 82 // This expression is here for better compressibility (see addClass) 83 cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 84 85 if ( cur ) { 86 for ( i = 0; i < classNames.length; i++ ) { 87 className = classNames[ i ]; 88 89 // Remove *all* instances 90 while ( cur.indexOf( " " + className + " " ) > -1 ) { 91 cur = cur.replace( " " + className + " ", " " ); 92 } 93 } 94 95 // Only assign if different to avoid unneeded rendering. 96 finalValue = stripAndCollapse( cur ); 97 if ( curValue !== finalValue ) { 98 this.setAttribute( "class", finalValue ); 99 } 100 } 101 } ); 102 } 103 104 return this; 105 }, 106 107 toggleClass: function( value, stateVal ) { 108 var classNames, className, i, self, 109 type = typeof value, 110 isValidValue = type === "string" || Array.isArray( value ); 111 112 if ( isFunction( value ) ) { 113 return this.each( function( i ) { 114 jQuery( this ).toggleClass( 115 value.call( this, i, getClass( this ), stateVal ), 116 stateVal 117 ); 118 } ); 119 } 120 121 if ( typeof stateVal === "boolean" && isValidValue ) { 122 return stateVal ? this.addClass( value ) : this.removeClass( value ); 123 } 124 125 classNames = classesToArray( value ); 126 127 return this.each( function() { 128 if ( isValidValue ) { 129 130 // Toggle individual class names 131 self = jQuery( this ); 132 133 for ( i = 0; i < classNames.length; i++ ) { 134 className = classNames[ i ]; 135 136 // Check each className given, space separated list 137 if ( self.hasClass( className ) ) { 138 self.removeClass( className ); 139 } else { 140 self.addClass( className ); 141 } 142 } 143 144 // Toggle whole class name 145 } else if ( value === undefined || type === "boolean" ) { 146 className = getClass( this ); 147 if ( className ) { 148 149 // Store className if set 150 dataPriv.set( this, "__className__", className ); 151 } 152 153 // If the element has a class name or if we're passed `false`, 154 // then remove the whole classname (if there was one, the above saved it). 155 // Otherwise bring back whatever was previously saved (if anything), 156 // falling back to the empty string if nothing was stored. 157 if ( this.setAttribute ) { 158 this.setAttribute( "class", 159 className || value === false ? 160 "" : 161 dataPriv.get( this, "__className__" ) || "" 162 ); 163 } 164 } 165 } ); 166 }, 167 168 hasClass: function( selector ) { 169 var className, elem, 170 i = 0; 171 172 className = " " + selector + " "; 173 while ( ( elem = this[ i++ ] ) ) { 174 if ( elem.nodeType === 1 && 175 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { 176 return true; 177 } 178 } 179 180 return false; 181 } 182 } ); 183 184 } );