🌐 AI搜索 & 代理 主页
Skip to content

Commit 5e6e538

Browse files
committed
toggleClass can now toggle multiple classNames (space seperated list) and toggle the whole className. fixes #3825.
1 parent d415e0a commit 5e6e538

File tree

2 files changed

+65
-20
lines changed

2 files changed

+65
-20
lines changed

src/attributes.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,25 @@ jQuery.each({
130130
},
131131

132132
toggleClass: function( classNames, state ) {
133-
if( typeof state !== "boolean" )
134-
state = !jQuery.className.has( this, classNames );
135-
jQuery.className[ state ? "add" : "remove" ]( this, classNames );
133+
var type = typeof classNames;
134+
if ( type === "string" ) {
135+
// toggle individual class names
136+
var isBool = typeof state === "boolean", className, i = 0,
137+
classNames = classNames.split( /\s+/ );
138+
while ( (className = classNames[ i++ ]) ) {
139+
// check each className given, space seperated list
140+
state = isBool ? state : !jQuery.className.has( this, className );
141+
jQuery.className[ state ? "add" : "remove" ]( this, className );
142+
}
143+
} else if ( type === "undefined" || type === "boolean" ) {
144+
// toggle whole className
145+
if ( this.className || classNames === false ) {
146+
jQuery.data( this, "__className__", this.className );
147+
this.className = "";
148+
} else {
149+
this.className = jQuery.data( this, "__className__" ) || "";
150+
}
151+
}
136152
}
137153
}, function(name, fn){
138154
jQuery.fn[ name ] = function(){

test/unit/attributes.js

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,19 @@ test("attr(String)", function() {
3333

3434
ok( $body.attr('foo') === undefined, 'Make sure that a non existent attribute returns undefined' );
3535
ok( $body.attr('nextSibling') === null, 'Make sure a null expando returns null' );
36-
36+
3737
body.setAttribute('foo', 'baz');
3838
equals( $body.attr('foo'), 'baz', 'Make sure the dom attribute is retrieved when no expando is found' );
39-
39+
4040
body.foo = 'bar';
4141
equals( $body.attr('foo'), 'bar', 'Make sure the expando is preferred over the dom attribute' );
42-
42+
4343
$body.attr('foo','cool');
4444
equals( $body.attr('foo'), 'cool', 'Make sure that setting works well when both expando and dom attribute are available' );
45-
45+
4646
body.foo = undefined;
4747
ok( $body.attr('foo') === undefined, 'Make sure the expando is preferred over the dom attribute, even if undefined' );
48-
48+
4949
body.removeAttribute('foo'); // Cleanup
5050
});
5151

@@ -141,7 +141,7 @@ test("attr(String, Object)", function() {
141141
}
142142
ok( thrown, "Exception thrown when trying to change type property" );
143143
equals( "checkbox", jQuery(check).attr('type'), "Verify that you can change the type of an input element that isn't in the DOM" );
144-
144+
145145
var check = jQuery("<input />");
146146
var thrown = true;
147147
try {
@@ -151,7 +151,7 @@ test("attr(String, Object)", function() {
151151
}
152152
ok( thrown, "Exception thrown when trying to change type property" );
153153
equals( "checkbox", check.attr('type'), "Verify that you can change the type of an input element that isn't in the DOM" );
154-
154+
155155
var button = jQuery("#button");
156156
var thrown = false;
157157
try {
@@ -185,7 +185,7 @@ test("attr('tabindex')", function() {
185185
// elements not natively tabbable
186186
equals(jQuery('#listWithTabIndex').attr('tabindex'), 5, 'not natively tabbable, with tabindex set to 0');
187187
equals(jQuery('#divWithNoTabIndex').attr('tabindex'), undefined, 'not natively tabbable, no tabindex set');
188-
188+
189189
// anchor with href
190190
equals(jQuery('#linkWithNoTabIndex').attr('tabindex'), 0, 'anchor with href, no tabindex set');
191191
equals(jQuery('#linkWithTabIndex').attr('tabindex'), 2, 'anchor with href, tabindex set to 2');
@@ -214,7 +214,7 @@ test("attr('tabindex', value)", function() {
214214
// set a negative string
215215
element.attr('tabindex', '-1');
216216
equals(element.attr('tabindex'), -1, 'set tabindex to -1 (string)');
217-
217+
218218
// set a positive number
219219
element.attr('tabindex', 1);
220220
equals(element.attr('tabindex'), 1, 'set tabindex to 1 (number)');
@@ -226,7 +226,7 @@ test("attr('tabindex', value)", function() {
226226
// set a negative number
227227
element.attr('tabindex', -1);
228228
equals(element.attr('tabindex'), -1, 'set tabindex to -1 (number)');
229-
229+
230230
element = jQuery('#linkWithTabIndex');
231231
equals(element.attr('tabindex'), 2, 'start with tabindex 2');
232232

@@ -252,26 +252,26 @@ test("addClass(String)", function() {
252252

253253
test("removeClass(String) - simple", function() {
254254
expect(5);
255-
255+
256256
var $divs = jQuery('div');
257-
257+
258258
$divs.addClass("test").removeClass("test");
259-
259+
260260
ok( !$divs.is('.test'), "Remove Class" );
261261

262262
reset();
263263

264264
$divs.addClass("test").addClass("foo").addClass("bar");
265265
$divs.removeClass("test").removeClass("bar").removeClass("foo");
266-
266+
267267
ok( !$divs.is('.test,.bar,.foo'), "Remove multiple classes" );
268268

269269
reset();
270270

271271
// Make sure that a null value doesn't cause problems
272272
$divs.eq(0).addClass("test").removeClass(null);
273273
ok( $divs.eq(0).is('.test'), "Null value passed to removeClass" );
274-
274+
275275
$divs.eq(0).addClass("test").removeClass("");
276276
ok( $divs.eq(0).is('.test'), "Empty string passed to removeClass" );
277277

@@ -281,21 +281,50 @@ test("removeClass(String) - simple", function() {
281281
ok( !j.hasClass("asdf"), "Check node,textnode,comment for removeClass" );
282282
});
283283

284-
test("toggleClass(String)", function() {
285-
expect(6);
284+
test("toggleClass(String|boolean|undefined[, boolean])", function() {
285+
expect(16);
286+
286287
var e = jQuery("#firstp");
287288
ok( !e.is(".test"), "Assert class not present" );
288289
e.toggleClass("test");
289290
ok( e.is(".test"), "Assert class present" );
290291
e.toggleClass("test");
291292
ok( !e.is(".test"), "Assert class not present" );
292293

294+
// class name with a boolean
293295
e.toggleClass("test", false);
294296
ok( !e.is(".test"), "Assert class not present" );
295297
e.toggleClass("test", true);
296298
ok( e.is(".test"), "Assert class present" );
297299
e.toggleClass("test", false);
298300
ok( !e.is(".test"), "Assert class not present" );
301+
302+
// multiple class names
303+
e.addClass("testA testB");
304+
ok( (e.is(".testA.testB")), "Assert 2 different classes present" );
305+
e.toggleClass("testB testC");
306+
ok( (e.is(".testA.testC") && !e.is(".testB")), "Assert 1 class added, 1 class removed, and 1 class kept" );
307+
e.toggleClass("testA testC");
308+
ok( (!e.is(".testA") && !e.is(".testB") && !e.is(".testC")), "Assert no class present" );
309+
310+
// toggleClass storage
311+
e.toggleClass(true);
312+
ok( e.get(0).className === "", "Assert class is empty (data was empty)" );
313+
e.addClass("testD");
314+
ok( e.is(".testD"), "Assert class present" );
315+
e.toggleClass();
316+
ok( !e.is(".testD"), "Assert class not present" );
317+
ok( e.data('__className__') === 'testD', "Assert data was stored" );
318+
e.toggleClass();
319+
ok( e.is(".testD"), "Assert class present (restored from data)" );
320+
e.toggleClass(false);
321+
ok( !e.is(".testD"), "Assert class not present" );
322+
e.toggleClass(true);
323+
ok( e.is(".testD"), "Assert class present (restored from data)" );
324+
325+
// Cleanup
326+
e.removeClass("testD");
327+
e.removeData('__className__');
299328
});
300329

301330
test("removeAttr(String", function() {

0 commit comments

Comments
 (0)