Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Polyfill: Element.prototype.classList for IE8/9, Safari.
/**
* Element.prototype.classList for IE8/9, Safari.
* @author Kerem Güneş <k-gun@mail.com>
* @copyright Released under the MIT License <https://opensource.org/licenses/MIT>
* @version 1.2
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
*/
;(function() {
// Helpers.
var trim = function(s) {
return s.replace(/^\s+|\s+$/g, '');
},
regExp = function(name) {
return new RegExp('(^|\\s+)'+ name +'(\\s+|$)');
},
forEach = function(list, fn, scope) {
for (var i = 0; i < list.length; i++) {
fn.call(scope, list[i]);
}
};
// Class list object with basic methods.
function ClassList(element) {
this.element = element;
}
ClassList.prototype = {
add: function() {
forEach(arguments, function(name) {
if (!this.contains(name)) {
this.element.className = trim(this.element.className +' '+ name);
}
}, this);
},
remove: function() {
forEach(arguments, function(name) {
this.element.className = trim(this.element.className.replace(regExp(name), ' '));
}, this);
},
toggle: function(name) {
return this.contains(name) ? (this.remove(name), false) : (this.add(name), true);
},
contains: function(name) {
return regExp(name).test(this.element.className);
},
item: function(i) {
return this.element.className.split(/\s+/)[i] || null;
},
// bonus
replace: function(oldName, newName) {
this.remove(oldName), this.add(newName);
}
};
// IE8/9, Safari
// Remove this if statements to override native classList.
if (!('classList' in Element.prototype)) {
// Use this if statement to override native classList that does not have for example replace() method.
// See browser compatibility: https://developer.mozilla.org/en-US/docs/Web/API/Element/classList#Browser_compatibility.
// if (!('classList' in Element.prototype) ||
// !('classList' in Element.prototype && Element.prototype.classList.replace)) {
Object.defineProperty(Element.prototype, 'classList', {
get: function() {
return new ClassList(this);
}
});
}
// For others replace() support.
if (window.DOMTokenList && !DOMTokenList.prototype.replace) {
DOMTokenList.prototype.replace = ClassList.prototype.replace;
}
})();
@ballercat

This comment has been minimized.

Copy link

commented Apr 13, 2017

Please fix line 21. There should be no extra space if className is already empty.

@desjardinsm

This comment has been minimized.

Copy link

commented Apr 25, 2017

Also on line 28, for the remove(), if the class being removed is in the middle of two other classes rather than an end (and if classes are delimited by only a single space), it loses the space and the surrounding class names get combined into one.

@k-gun

This comment has been minimized.

Copy link
Owner Author

commented Aug 22, 2017

@ballercat; even it is not worth to deal with empty class, fixed it.
@desjardinsm; that was a good catch, thank you, fixed.

And added item() and other trivial stuff, comments etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.