Skip to content

Instantly share code, notes, and snippets.

@devongovett
Created November 21, 2011 06:31
Show Gist options
  • Save devongovett/1381839 to your computer and use it in GitHub Desktop.
Save devongovett/1381839 to your computer and use it in GitHub Desktop.
/*
* Minimal classList shim for IE 9
* By Devon Govett
* MIT LICENSE
*/
if (!("classList" in document.documentElement) && Object.defineProperty && typeof HTMLElement !== 'undefined') {
Object.defineProperty(HTMLElement.prototype, 'classList', {
get: function() {
var self = this;
function update(fn) {
return function(value) {
var classes = self.className.split(/\s+/),
index = classes.indexOf(value);
fn(classes, index, value);
self.className = classes.join(" ");
}
}
var ret = {
add: update(function(classes, index, value) {
~index || classes.push(value);
}),
remove: update(function(classes, index) {
~index && classes.splice(index, 1);
}),
toggle: update(function(classes, index, value) {
~index ? classes.splice(index, 1) : classes.push(value);
}),
contains: function(value) {
return !!~self.className.split(/\s+/).indexOf(value);
},
item: function(i) {
return self.className.split(/\s+/)[i] || null;
}
};
Object.defineProperty(ret, 'length', {
get: function() {
return self.className.split(/\s+/).length;
}
});
return ret;
}
});
}
@rwaldron
Copy link

@jdalton
Copy link

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
Copy link
Author

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

@devongovett
Copy link
Author

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

@jdalton
Copy link

jdalton commented Nov 21, 2011

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

@devongovett
Copy link
Author

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

@jdalton
Copy link

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
Copy link

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

@devongovett
Copy link
Author

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
Copy link

Word.

@eligrey
Copy link

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