Created
February 14, 2013 07:50
-
-
Save rainyjune/4951208 to your computer and use it in GitHub Desktop.
classList(): treat className as a set of CSS classes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Return the classList property of e, if it has one. | |
* Otherwise, return an object that simulates the DOMTokenList API for e. | |
* The returned object has contains(), add(), remove(), toggle() and toString() | |
* methods for testing and altering the set of classes of the element e. | |
* If the classList property is natively supported, the returned object is | |
* array-like and has length and array index properties. The simulated | |
* DOMTokenList is not array-like, but has a toArray() method that returns | |
* a true-array snapshot of the element's class names. | |
*/ | |
function classList(e) { | |
if (e.classList) return e.classList; // Return e.classList if it exists | |
else return new CSSClassList(e); // Otherwise try to fake it | |
} | |
// CSSClassList is a JavaScript class that simulates DOMTokenList | |
function CSSClassList(e) { this.e = e; } | |
// Return true if e.className contains the class c, false otherwise | |
CSSClassList.prototype.contains = function(c) { | |
// Check that c is a valid class name | |
if (c.length === 0 || c.indexOf(" ") != -1) | |
throw new Error("Invalid class name: '" + c + "'"); | |
// Check common cases first | |
var classes = this.e.className; | |
if (!classes) return false; // e has no classes at all | |
if (classes === c) return true; // e has one class that matches exactly | |
// Otherwise, use a RegExp to search for c as a word by itself | |
// \b in a regular expression requires a match at a word boundary. | |
return classes.search("\\b" + c + "\\b") != -1; | |
}; | |
// Add c to the e.className if it is not already present | |
CSSClassList.prototype.add = function(c) { | |
if (this.contains(c)) return; // Do nothing if already present | |
var classes = this.e.className; | |
if (classes && classes[classes.length-1] != " ") | |
c = " " + c; // Add a space if we need one | |
this.e.className += c; // Add c to the className | |
}; | |
// Remove all occurrences of c from e.className | |
CSSClassList.prototype.remove = function(c) { | |
// Make sure c is a valid class name | |
if (c.length === 0 || c.indexOf(" ") != -1) | |
throw new Error("Invalid class name: '" + c + "'"); | |
// Remove all occurances of c as a word, plus any trailing space | |
var pattern = new RegExp("\\b" + c + "\\b\\s*", "g"); | |
this.e.className = this.e.className.replace(pattern, ""); | |
}; | |
// Add c to e.className if it is not already present and return true. | |
// Otherwise, remove all occurrences of c from e.className and return false. | |
CSSClassList.prototype.toggle = function(c) { | |
if (this.contains(c)) { // If e.className contains c | |
this.remove(c); // then remove it. | |
return false; | |
} | |
else { // Otherwise: | |
this.add(c); // add it. | |
return true; | |
} | |
}; | |
// Return e.className itself | |
CSSClassList.prototype.toString = function() { return this.e.className; }; | |
// Return of the names in e.className | |
CSSClassList.prototype.toArray = function() { | |
return this.e.className.match(/\b\w+\b/g) || []; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment