Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
/*
* Minimal classList shim
* By Devon Govett
* MIT LICENSE
*/
if (!("classList" in document.documentElement)) {
Object.defineProperty(HTMLElement.prototype, 'classList', {
get: function() {
var self = this;
function update(fn) {
return function(value) {
var classes = self.className.split(/\s+/g),
index = classes.indexOf(value);
fn(classes, index, value);
self.className = classes.join(" ");
}
}
return {
add: update(function(classes, index, value) {
if (!~index) classes.push(value);
}),
remove: update(function(classes, index) {
if (~index) classes.splice(index, 1);
}),
toggle: update(function(classes, index, value) {
if (~index)
classes.splice(index, 1);
else
classes.push(value);
}),
contains: function(value) {
return !!~self.className.split(/\s+/g).indexOf(value);
},
item: function(i) {
return self.className.split(/\s+/g)[i] || null;
}
};
}
});
}
@rwaldron

This comment has been minimized.

Show comment Hide comment
@rwaldron

rwaldron Nov 21, 2011

I wonder if those browsers that are missing classList support would have DOMTokenList support, which would be the base proto of classList...

I wonder if those browsers that are missing classList support would have DOMTokenList support, which would be the base proto of classList...

@jdalton

This comment has been minimized.

Show comment Hide comment
@jdalton

jdalton Nov 21, 2011

@devongovett Look to how some of the selector engines like Sizzle or NWMatcher detect class names. They have refined them for speed, at first glance yur class name operations look a little costly. Also extending the DOM leads to nothing but headache and dev tears.

jdalton commented Nov 21, 2011

@devongovett Look to how some of the selector engines like Sizzle or NWMatcher detect class names. They have refined them for speed, at first glance yur class name operations look a little costly. Also extending the DOM leads to nothing but headache and dev tears.

@devongovett

This comment has been minimized.

Show comment Hide comment
@devongovett

devongovett Nov 21, 2011

That's exactly what it is supposed to be though - a polyfill. And I agree it can probably be improved but it was designed to be really small and I wrote it in about 5 minutes. :) If you've got improvements, by all means have at it.

Owner

devongovett commented Nov 21, 2011

That's exactly what it is supposed to be though - a polyfill. And I agree it can probably be improved but it was designed to be really small and I wrote it in about 5 minutes. :) If you've got improvements, by all means have at it.

@jdalton

This comment has been minimized.

Show comment Hide comment
@jdalton

jdalton Nov 21, 2011

@devongovett Polyfill or not, extending the DOM has been known to cause problems. Would be better if you made a small utility method that leveraged native functionality or forked for a fallback.

jdalton commented Nov 21, 2011

@devongovett Polyfill or not, extending the DOM has been known to cause problems. Would be better if you made a small utility method that leveraged native functionality or forked for a fallback.

@devongovett

This comment has been minimized.

Show comment Hide comment
@devongovett

devongovett Nov 21, 2011

If you don't want to extend the DOM, don't use this shim. What problems do you see? It seems to work for me...

Owner

devongovett commented Nov 21, 2011

If you don't want to extend the DOM, don't use this shim. What problems do you see? It seems to work for me...

@jdalton

This comment has been minimized.

Show comment Hide comment
@jdalton

jdalton Nov 21, 2011

@devongovett I'm trying to save you some heart burn by giving you a heads up. I've spent many years working with libs like Prototype that extend the DOM and a lot of the time things seemed to work fine, for a time, but then fell apart down the road.

jdalton commented Nov 21, 2011

@devongovett I'm trying to save you some heart burn by giving you a heads up. I've spent many years working with libs like Prototype that extend the DOM and a lot of the time things seemed to work fine, for a time, but then fell apart down the road.

@rwaldron

This comment has been minimized.

Show comment Hide comment
@rwaldron

rwaldron Nov 21, 2011

@jdalton

This comment has been minimized.

Show comment Hide comment
@jdalton

jdalton Nov 21, 2011

I understand support was aimed at IE8/9 but this causes script errors in IE 6/7 and 8.
IE 8 has window.Element but not window.HTMLElement.

jdalton commented Nov 21, 2011

I understand support was aimed at IE8/9 but this causes script errors in IE 6/7 and 8.
IE 8 has window.Element but not window.HTMLElement.

@devongovett

This comment has been minimized.

Show comment Hide comment
@devongovett

devongovett Nov 21, 2011

It doesn't have Object.defineProperty either... better?

Owner

devongovett commented Nov 21, 2011

It doesn't have Object.defineProperty either... better?

@devongovett

This comment has been minimized.

Show comment Hide comment
@devongovett

devongovett Nov 21, 2011

@rwldrn wouldn't length be better implemented as a getter? Otherwise if the user updates the className the length won't change.

Owner

devongovett commented Nov 21, 2011

@rwldrn wouldn't length be better implemented as a getter? Otherwise if the user updates the className the length won't change.

@jdalton

This comment has been minimized.

Show comment Hide comment
@jdalton

jdalton Nov 21, 2011

@devongovett IE8 has Object.defineProperty. In fact, IE8's Object.defineProperty only works on DOM elements ;D

jdalton commented Nov 21, 2011

@devongovett IE8 has Object.defineProperty. In fact, IE8's Object.defineProperty only works on DOM elements ;D

@devongovett

This comment has been minimized.

Show comment Hide comment
@devongovett

devongovett Nov 21, 2011

Yeah I realize that. I was referring to IE 6 and 7. Unfortunately the length getter wouldn't work in IE 8 either.

Owner

devongovett commented Nov 21, 2011

Yeah I realize that. I was referring to IE 6 and 7. Unfortunately the length getter wouldn't work in IE 8 either.

@jdalton

This comment has been minimized.

Show comment Hide comment
@jdalton

jdalton Nov 21, 2011

@devongovett In IE8 HTMLElement will be an undefined var reference and throw an error.

Also another heads up, String#split and IE are iffy when it comes to regexp support (rule of thumb: keep it really simple and test).
Your regexp could be simplified to just /\s+/.

jdalton commented Nov 21, 2011

@devongovett In IE8 HTMLElement will be an undefined var reference and throw an error.

Also another heads up, String#split and IE are iffy when it comes to regexp support (rule of thumb: keep it really simple and test).
Your regexp could be simplified to just /\s+/.

@rwaldron

This comment has been minimized.

Show comment Hide comment
@rwaldron

rwaldron Nov 21, 2011

@devongovett - it sure would, but like I said it's "half-assed" and only meant to work in IE8 right?

@devongovett - it sure would, but like I said it's "half-assed" and only meant to work in IE8 right?

@devongovett

This comment has been minimized.

Show comment Hide comment
@devongovett

devongovett Nov 21, 2011

Eh! Screw IE < 9. Too many problems and I wasn't trying to support it in my app anyway. The regex is now simplified, and I added "real" length support via a getter. And to answer your question @rwldrn, it looks like IE does not have DOMTokenList.

Owner

devongovett commented Nov 21, 2011

Eh! Screw IE < 9. Too many problems and I wasn't trying to support it in my app anyway. The regex is now simplified, and I added "real" length support via a getter. And to answer your question @rwldrn, it looks like IE does not have DOMTokenList.

@rwaldron

This comment has been minimized.

Show comment Hide comment
@rwaldron

rwaldron Nov 21, 2011

Word.

Word.

@eligrey

This comment has been minimized.

Show comment Hide comment
@eligrey

eligrey Feb 8, 2012

Super late to this party, but my classList polyfill has true native .length by being an array (i.e. constructor's .prototype = []). You could try something like that.

eligrey commented Feb 8, 2012

Super late to this party, but my classList polyfill has true native .length by being an array (i.e. constructor's .prototype = []). You could try something like that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment