mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
CSS: Skip falsy values in addClass( array )
, compress code
This change makes jQuery skip falsy values in `addClass( array )` & `removeClass( array )` instead of stopping iteration when the first falsy value is detected. This makes code like: ```js elem.addClass( [ "a", "", "b" ] ); ``` add both the `a` & `b` classes. The code was also optimized for size a bit so it doesn't increase the minified gzipped size. Fixes gh-4998 Closes gh-5003
This commit is contained in:
parent
9c6f64c7b5
commit
a338b407f2
@ -20,8 +20,7 @@ function classesToArray( value ) {
|
||||
|
||||
jQuery.fn.extend( {
|
||||
addClass: function( value ) {
|
||||
var classes, elem, cur, curValue, clazz, j, finalValue,
|
||||
i = 0;
|
||||
var classNames, cur, curValue, className, i, finalValue;
|
||||
|
||||
if ( typeof value === "function" ) {
|
||||
return this.each( function( j ) {
|
||||
@ -29,36 +28,35 @@ jQuery.fn.extend( {
|
||||
} );
|
||||
}
|
||||
|
||||
classes = classesToArray( value );
|
||||
classNames = classesToArray( value );
|
||||
|
||||
if ( classes.length ) {
|
||||
while ( ( elem = this[ i++ ] ) ) {
|
||||
curValue = getClass( elem );
|
||||
cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
|
||||
if ( classNames.length ) {
|
||||
return this.each( function() {
|
||||
curValue = getClass( this );
|
||||
cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
|
||||
|
||||
if ( cur ) {
|
||||
j = 0;
|
||||
while ( ( clazz = classes[ j++ ] ) ) {
|
||||
if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
|
||||
cur += clazz + " ";
|
||||
for ( i = 0; i < classNames.length; i++ ) {
|
||||
className = classNames[ i ];
|
||||
if ( cur.indexOf( " " + className + " " ) < 0 ) {
|
||||
cur += className + " ";
|
||||
}
|
||||
}
|
||||
|
||||
// Only assign if different to avoid unneeded rendering.
|
||||
finalValue = stripAndCollapse( cur );
|
||||
if ( curValue !== finalValue ) {
|
||||
elem.setAttribute( "class", finalValue );
|
||||
this.setAttribute( "class", finalValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
removeClass: function( value ) {
|
||||
var classes, elem, cur, curValue, clazz, j, finalValue,
|
||||
i = 0;
|
||||
var classNames, cur, curValue, className, i, finalValue;
|
||||
|
||||
if ( typeof value === "function" ) {
|
||||
return this.each( function( j ) {
|
||||
@ -70,38 +68,40 @@ jQuery.fn.extend( {
|
||||
return this.attr( "class", "" );
|
||||
}
|
||||
|
||||
classes = classesToArray( value );
|
||||
classNames = classesToArray( value );
|
||||
|
||||
if ( classes.length ) {
|
||||
while ( ( elem = this[ i++ ] ) ) {
|
||||
curValue = getClass( elem );
|
||||
if ( classNames.length ) {
|
||||
return this.each( function() {
|
||||
curValue = getClass( this );
|
||||
|
||||
// This expression is here for better compressibility (see addClass)
|
||||
cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
|
||||
cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
|
||||
|
||||
if ( cur ) {
|
||||
j = 0;
|
||||
while ( ( clazz = classes[ j++ ] ) ) {
|
||||
for ( i = 0; i < classNames.length; i++ ) {
|
||||
className = classNames[ i ];
|
||||
|
||||
// Remove *all* instances
|
||||
while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
|
||||
cur = cur.replace( " " + clazz + " ", " " );
|
||||
while ( cur.indexOf( " " + className + " " ) > -1 ) {
|
||||
cur = cur.replace( " " + className + " ", " " );
|
||||
}
|
||||
}
|
||||
|
||||
// Only assign if different to avoid unneeded rendering.
|
||||
finalValue = stripAndCollapse( cur );
|
||||
if ( curValue !== finalValue ) {
|
||||
elem.setAttribute( "class", finalValue );
|
||||
this.setAttribute( "class", finalValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
toggleClass: function( value, stateVal ) {
|
||||
var classNames, className, i, self;
|
||||
|
||||
if ( typeof value === "function" ) {
|
||||
return this.each( function( i ) {
|
||||
jQuery( this ).toggleClass(
|
||||
@ -115,24 +115,28 @@ jQuery.fn.extend( {
|
||||
return stateVal ? this.addClass( value ) : this.removeClass( value );
|
||||
}
|
||||
|
||||
return this.each( function() {
|
||||
var className, i, self, classNames;
|
||||
classNames = classesToArray( value );
|
||||
|
||||
// Toggle individual class names
|
||||
i = 0;
|
||||
self = jQuery( this );
|
||||
classNames = classesToArray( value );
|
||||
if ( classNames.length ) {
|
||||
return this.each( function() {
|
||||
|
||||
while ( ( className = classNames[ i++ ] ) ) {
|
||||
// Toggle individual class names
|
||||
self = jQuery( this );
|
||||
|
||||
// Check each className given, space separated list
|
||||
if ( self.hasClass( className ) ) {
|
||||
self.removeClass( className );
|
||||
} else {
|
||||
self.addClass( className );
|
||||
for ( i = 0; i < classNames.length; i++ ) {
|
||||
className = classNames[ i ];
|
||||
|
||||
// Check each className given, space separated list
|
||||
if ( self.hasClass( className ) ) {
|
||||
self.removeClass( className );
|
||||
} else {
|
||||
self.addClass( className );
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
hasClass: function( selector ) {
|
||||
|
@ -1644,6 +1644,44 @@ QUnit.test( "addClass, removeClass, hasClass on elements with classes with non-H
|
||||
testMatches();
|
||||
} );
|
||||
|
||||
( function() {
|
||||
var rnothtmlwhite = /[^\x20\t\r\n\f]+/g;
|
||||
|
||||
function expectClasses( assert, elem, classes ) {
|
||||
var actualClassesSorted = ( elem.attr( "class" ).match( rnothtmlwhite ) || [] )
|
||||
.sort().join( " " );
|
||||
var classesSorted = classes.slice()
|
||||
.sort().join( " " );
|
||||
assert.equal( actualClassesSorted, classesSorted, "Expected classes present" );
|
||||
}
|
||||
|
||||
QUnit.test( "addClass on arrays with falsy elements (gh-4998)", function( assert ) {
|
||||
assert.expect( 3 );
|
||||
|
||||
var elem = jQuery( "<div class='a'></div>" );
|
||||
|
||||
elem.addClass( [ "b", "", "c" ] );
|
||||
expectClasses( assert, elem, [ "a", "b", "c" ] );
|
||||
elem.addClass( [ "", "d" ] );
|
||||
expectClasses( assert, elem, [ "a", "b", "c", "d" ] );
|
||||
elem.addClass( [ "e", "" ] );
|
||||
expectClasses( assert, elem, [ "a", "b", "c", "d", "e" ] );
|
||||
} );
|
||||
|
||||
QUnit.test( "removeClass on arrays with falsy elements (gh-4998)", function( assert ) {
|
||||
assert.expect( 3 );
|
||||
|
||||
var elem = jQuery( "<div class='a b c d e'></div>" );
|
||||
|
||||
elem.removeClass( [ "e", "" ] );
|
||||
expectClasses( assert, elem, [ "a", "b", "c", "d" ] );
|
||||
elem.removeClass( [ "", "d" ] );
|
||||
expectClasses( assert, elem, [ "a", "b", "c" ] );
|
||||
elem.removeClass( [ "b", "", "c" ] );
|
||||
expectClasses( assert, elem, [ "a" ] );
|
||||
} );
|
||||
} )();
|
||||
|
||||
QUnit.test( "contents().hasClass() returns correct values", function( assert ) {
|
||||
assert.expect( 2 );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user