Skip to content

Instantly share code, notes, and snippets.

@mwrouse
Last active April 13, 2017 14:27
Show Gist options
  • Save mwrouse/8e51c3b640dc6b82d1362ea7e9911b42 to your computer and use it in GitHub Desktop.
Save mwrouse/8e51c3b640dc6b82d1362ea7e9911b42 to your computer and use it in GitHub Desktop.
classList polyfill for IE7+ and all major browsers
/**
* ClassList polyfill for IE7+ and all major browsers
* By: Michael Rouse
*
* Use:
* var my_element = document.getElementById('major-id');
*
* classList.add(my_element, 'new-class'); // Adds the class 'new-class' to the element
* classList.remove(my_element, 'old-class'); // Removes 'old-class' from the element's classes
* classList.contains(my_element, 'a-class'); // Returns true if the element has 'a-class' as a class
* classList.toggle(my_element, 'invalid'); // Toggles the invalid class on the element (if it already has it, it will be removed, otherwise it will be added)
* classList.item(my_element, 'my-class'); // Returns the index of 'my-class' in the element's class list, -1 if it does not exist
*
* Alternatively:
* var my_element = classListPolyfill(document.getElementById('minor-id'));
*
* my_element.classList.add('new-class');
* my_element.classList.remove('old-class');
* my_element.classList.contains('a-class');
* my_element.classList.toggle('invalid');
* my_element.classList.item('my-class');
*
*/
var classList = {
// Checks if the element contains a class
contains: function(el, class_name) {
if (!el || typeof el !== "object") throw new TypeError("First parameter of classList.contains must be an Object");
if (!class_name || typeof class_name !== "string") throw new TypeError("Second parameter of classList.contains must be a string");
if (el.className === undefined) return false; // Can't perform polyfill
var classes = el.className.split(" ");
for (var i = 0; i < classes.length; i++)
{
if (classes[i] === class_name)
return true;
}
return false; // Does not contain the class
}, // End contains
// Adds a class
add: function(el, class_name) {
if (!el || typeof el !== "object") throw new TypeError("First parameter of classList.add must be an Object");
if (!class_name || typeof class_name !== "string") throw new TypeError("Second parameter of classList.add must be a string");
// Check if the polyfill is needed
if (el.className === undefined) return; // Can't perform polyfill
if (this.contains(el, class_name)) return; // Class already exists on the element
el.className = (el.className.isEmpty() ? "" : " ") + class_name; // Add to the list
}, // End add
// Removes a class
remove: function(el, class_name) {
if (!el || typeof el !== "object") throw new TypeError("First parameter of classList.remove must be an Object");
if (!class_name || typeof class_name !== "string") throw new TypeError("Second parameter of classList.remove must be a string");
if (el.className === undefined) return; // Can't perform polyfill
var classes = el.className.split(" " );
el.className = "";
for (var i = 0; i < classes.length; i++)
{
if (classes[i] != class_name)
el.className += (el.className.isEmpty() ? "" : " ") + classes[i];
}
}, // End remove
// Returns the class name at an index
item: function(el, index) {
if (!el || typeof el !== "object") throw new TypeError("First parameter of classList.item must be an Object");
if (!index || typeof index !== "number") throw new TypeError("Second parameter of classList.item must be a number");
if (el.className === undefined) return; // Can't perform polyfill
var classes = el.className.split(" ");
if ((classes.length - 1) >= index)
return classes[index];
else
return -1; // Does not exist
}, // End item
// Toggles a class
toggle: function(el, class_name, force) {
if (!el || typeof el !== "object") throw new TypeError("First parameter of classList.force must be an Object");
if (!class_name || typeof class_name !== "string") throw new TypeError("Second parameter of classList.force must be a string");
if (force && typeof force !== "boolean") throw new TypeError("Third parameter of classList.force must be a boolean");
if (force == undefined)
{
var contains = this.contains(el, class_name);
if (contains)
this.remove(el, class_name); // Remove the class
else
this.add(el, class_name); // Add the class
return !contains; // Returns true if added, false if removed
}
else
{
// Force add or remove
if (force == true)
this.add(el, class_name);
else
this.remove(el, class_name);
return force;
}
} // End toggle
};
/**
* Function to polyfill an object
*/
function classListPolyfill(el)
{
if (!el || el.classList) return el;
el.classList = (function () {
return {
contains: function(class_name) {
return classList.contains(el, class_name);
},
add: function(class_name) {
return classList.add(el, class_name);
},
remove: function(class_name) {
return classList.remove(el, class_name);
},
item: function(index) {
return classList.item(el, index);
},
toggle: function(class_name, force) {
return classList.toggle(el, class_name, force);
}
};
}());
return el;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment