element.classList

  • Revision slug: Web/API/Element.classList
  • Revision title: element.classList
  • Revision id: 483113
  • Created:
  • Creator: JaredWein
  • Is current revision? No
  • Comment

Revision Content

{{DomRef}}

Summary

classList returns a token list of the class attribute of the element.

classList is a convenient alternative to accessing an element's list of classes as a space-delimited string via {{domxref("element.className")}}. It makes it easier to accomplish common tasks:

  • add a class to an element's list of classes
  • remove a class from an element's list of classes
  • toggle the existence of a class in an element's list of classes
  • check if an element's list of classes contains a specific class

Syntax

var elementClasses = elementNodeReference.classList;

elementClasses is a DOMTokenList representing the class attribute of elementNodeReference. If the class attribute was not set or is empty elementClasses.length returns 0. element.classList itself is read-only, although you can modify it using the add() and remove() methods.

The toggle method has an optional second argument that will force the class name to be added or removed based on the truthiness of the second argument. For example, to remove a class (if it exists or not) you can call element.classList.toggle('classToBeRemoved', false); and to add a class (if it exists or not) you can call element.classList.toggle('classToBeAdded', true);

Example

// div is an object reference to a <div> element with class="foo bar"
div.classList.remove("foo");
div.classList.add("anotherclass");

// if visible is set remove it, otherwise add it
div.classList.toggle("visible");

alert(div.classList.contains("foo"));

div.classList.add("foo","bar"); //add multiple classes

Currently, Firefox does not implement the use of several arguments in the add/remove/toggle methods

JavaScript shim for other implementations

Note: This shim does not work in Internet Explorer versions less than 8.
/*
 * classList.js: Cross-browser full element.classList implementation.
 * 2012-11-15
 *
 * By Eli Grey, http://eligrey.com
 * Public Domain.
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */

/*global self, document, DOMException */

/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/

if (typeof document !== "undefined" && !("classList" in document.documentElement)) {

(function (view) {

"use strict";

if (!('HTMLElement' in view) && !('Element' in view)) return;

var
	  classListProp = "classList"
	, protoProp = "prototype"
	, elemCtrProto = (view.HTMLElement || view.Element)[protoProp]
	, objCtr = Object
	, strTrim = String[protoProp].trim || function () {
		return this.replace(/^\s+|\s+$/g, "");
	}
	, arrIndexOf = Array[protoProp].indexOf || function (item) {
		var
			  i = 0
			, len = this.length
		;
		for (; i < len; i++) {
			if (i in this && this[i] === item) {
				return i;
			}
		}
		return -1;
	}
	// Vendors: please allow content code to instantiate DOMExceptions
	, DOMEx = function (type, message) {
		this.name = type;
		this.code = DOMException[type];
		this.message = message;
	}
	, checkTokenAndGetIndex = function (classList, token) {
		if (token === "") {
			throw new DOMEx(
				  "SYNTAX_ERR"
				, "An invalid or illegal string was specified"
			);
		}
		if (/\s/.test(token)) {
			throw new DOMEx(
				  "INVALID_CHARACTER_ERR"
				, "String contains an invalid character"
			);
		}
		return arrIndexOf.call(classList, token);
	}
	, ClassList = function (elem) {
		var
			  trimmedClasses = strTrim.call(elem.className)
			, classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
			, i = 0
			, len = classes.length
		;
		for (; i < len; i++) {
			this.push(classes[i]);
		}
		this._updateClassName = function () {
			elem.className = this.toString();
		};
	}
	, classListProto = ClassList[protoProp] = []
	, classListGetter = function () {
		return new ClassList(this);
	}
;
// Most DOMException implementations don't allow calling DOMException's toString()
// on non-DOMExceptions. Error's toString() is sufficient here.
DOMEx[protoProp] = Error[protoProp];
classListProto.item = function (i) {
	return this[i] || null;
};
classListProto.contains = function (token) {
	token += "";
	return checkTokenAndGetIndex(this, token) !== -1;
};
classListProto.add = function () {
	var
		  tokens = arguments
		, i = 0
		, l = tokens.length
		, token
		, updated = false
	;
	do {
		token = tokens[i] + "";
		if (checkTokenAndGetIndex(this, token) === -1) {
			this.push(token);
			updated = true;
		}
	}
	while (++i < l);

	if (updated) {
		this._updateClassName();
	}
};
classListProto.remove = function () {
	var
		  tokens = arguments
		, i = 0
		, l = tokens.length
		, token
		, updated = false
	;
	do {
		token = tokens[i] + "";
		var index = checkTokenAndGetIndex(this, token);
		if (index !== -1) {
			this.splice(index, 1);
			updated = true;
		}
	}
	while (++i < l);

	if (updated) {
		this._updateClassName();
	}
};
classListProto.toggle = function (token, forse) {
	token += "";

	var
		  result = this.contains(token)
		, method = result ?
			forse !== true && "remove"
		:
			forse !== false && "add"
	;

	if (method) {
		this[method](token);
	}

	return !result;
};
classListProto.toString = function () {
	return this.join(" ");
};

if (objCtr.defineProperty) {
	var classListPropDesc = {
		  get: classListGetter
		, enumerable: true
		, configurable: true
	};
	try {
		objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
	} catch (ex) { // IE 8 doesn't support enumerable:true
		if (ex.number === -0x7FF5EC54) {
			classListPropDesc.enumerable = false;
			objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
		}
	}
} else if (objCtr[protoProp].__defineGetter__) {
	elemCtrProto.__defineGetter__(classListProp, classListGetter);
}

}(self));

}

Browser compatibility

{{CompatibilityTable}}
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Basic support 8.0 {{ CompatGeckoDesktop("1.9.2") }} 10 11.50 5.1
{{Webkitbug("20709")}}
toggle method's second argument 24 {{CompatGeckoDesktop("24")}} no (IE 11 preview) 15 yes
{{Webkitbug("99375")}}

 

Feature Android Firefox Mobile (Gecko) IE Phone Opera Mobile Safari Mobile
Basic support 3.0 {{CompatGeckoMobile("1.9.2")}} 10 11.10 5.0
toggle method's second argument ? {{CompatGeckoMobile("24")}} ? ? ?

Specification

See also

Revision Source

<div>
  {{DomRef}}</div>
<h2 id="Summary">Summary</h2>
<p><strong>classList</strong> returns a token list of the class attribute of the element.</p>
<p>classList is a convenient alternative to accessing an element's list of classes as a space-delimited string via {{domxref("element.className")}}. It makes it easier to accomplish common tasks:</p>
<ul>
  <li><strong>add</strong> a class to an element's list of classes</li>
  <li><strong>remove</strong> a class from an element's list of classes</li>
  <li><strong>toggle</strong> the existence of a class in an element's list of classes</li>
  <li>check if an element's list of classes <strong>contains</strong> a specific class</li>
</ul>
<h2 id="Syntax" name="Syntax">Syntax</h2>
<pre class="syntaxbox">
var <var>elementClasses</var> = elementNodeReference.classList;
</pre>
<p><em>elementClasses</em> is a <a href="/en-US/docs/DOM/DOMTokenList" title="DOM/DOMTokenList">DOMTokenList</a> representing the class attribute of <em>elementNodeReference</em>. If the class attribute was not set or is empty <em>elementClasses.length</em> returns 0. <code>element.classList</code> itself is read-only, although you can modify it using the<code> add()</code> and <code>remove()</code> methods.</p>
<p>The <strong>toggle</strong> method has an optional second argument that will force the class name to be added or removed based on the truthiness of the second argument. For example, to remove a class (if it exists or not) you can call <code>element.classList.toggle('classToBeRemoved', false);</code> and to add a class (if it exists or not) you can call <code>element.classList.toggle('classToBeAdded', true);</code></p>
<h2 id="Example">Example</h2>
<pre class="brush: js">
// div is an object reference to a &lt;div&gt; element with class="foo bar"
div.classList.remove("foo");
div.classList.add("anotherclass");

// if visible is set remove it, otherwise add it
div.classList.toggle("visible");

alert(div.classList.contains("foo"));

div.classList.add("foo","bar"); //add multiple classes</pre>
<div class="note">
  <p>Currently, Firefox does not implement the use of several arguments in the add/remove/toggle methods</p>
</div>
<h2 id="wrapper" name="wrapper">JavaScript shim for other implementations</h2>
<div class="note">
  <strong>Note:</strong> This shim does not work in Internet Explorer versions less than 8.</div>
<pre class="brush: js">
/*
 * classList.js: Cross-browser full element.classList implementation.
 * 2012-11-15
 *
 * By Eli Grey, http://eligrey.com
 * Public Domain.
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */

/*global self, document, DOMException */

/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/

if (typeof document !== "undefined" &amp;&amp; !("classList" in document.documentElement)) {

(function (view) {

"use strict";

if (!('HTMLElement' in view) &amp;&amp; !('Element' in view)) return;

var
	  classListProp = "classList"
	, protoProp = "prototype"
	, elemCtrProto = (view.HTMLElement || view.Element)[protoProp]
	, objCtr = Object
	, strTrim = String[protoProp].trim || function () {
		return this.replace(/^\s+|\s+$/g, "");
	}
	, arrIndexOf = Array[protoProp].indexOf || function (item) {
		var
			  i = 0
			, len = this.length
		;
		for (; i &lt; len; i++) {
			if (i in this &amp;&amp; this[i] === item) {
				return i;
			}
		}
		return -1;
	}
	// Vendors: please allow content code to instantiate DOMExceptions
	, DOMEx = function (type, message) {
		this.name = type;
		this.code = DOMException[type];
		this.message = message;
	}
	, checkTokenAndGetIndex = function (classList, token) {
		if (token === "") {
			throw new DOMEx(
				  "SYNTAX_ERR"
				, "An invalid or illegal string was specified"
			);
		}
		if (/\s/.test(token)) {
			throw new DOMEx(
				  "INVALID_CHARACTER_ERR"
				, "String contains an invalid character"
			);
		}
		return arrIndexOf.call(classList, token);
	}
	, ClassList = function (elem) {
		var
			  trimmedClasses = strTrim.call(elem.className)
			, classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
			, i = 0
			, len = classes.length
		;
		for (; i &lt; len; i++) {
			this.push(classes[i]);
		}
		this._updateClassName = function () {
			elem.className = this.toString();
		};
	}
	, classListProto = ClassList[protoProp] = []
	, classListGetter = function () {
		return new ClassList(this);
	}
;
// Most DOMException implementations don't allow calling DOMException's toString()
// on non-DOMExceptions. Error's toString() is sufficient here.
DOMEx[protoProp] = Error[protoProp];
classListProto.item = function (i) {
	return this[i] || null;
};
classListProto.contains = function (token) {
	token += "";
	return checkTokenAndGetIndex(this, token) !== -1;
};
classListProto.add = function () {
	var
		  tokens = arguments
		, i = 0
		, l = tokens.length
		, token
		, updated = false
	;
	do {
		token = tokens[i] + "";
		if (checkTokenAndGetIndex(this, token) === -1) {
			this.push(token);
			updated = true;
		}
	}
	while (++i &lt; l);

	if (updated) {
		this._updateClassName();
	}
};
classListProto.remove = function () {
	var
		  tokens = arguments
		, i = 0
		, l = tokens.length
		, token
		, updated = false
	;
	do {
		token = tokens[i] + "";
		var index = checkTokenAndGetIndex(this, token);
		if (index !== -1) {
			this.splice(index, 1);
			updated = true;
		}
	}
	while (++i &lt; l);

	if (updated) {
		this._updateClassName();
	}
};
classListProto.toggle = function (token, forse) {
	token += "";

	var
		  result = this.contains(token)
		, method = result ?
			forse !== true &amp;&amp; "remove"
		:
			forse !== false &amp;&amp; "add"
	;

	if (method) {
		this[method](token);
	}

	return !result;
};
classListProto.toString = function () {
	return this.join(" ");
};

if (objCtr.defineProperty) {
	var classListPropDesc = {
		  get: classListGetter
		, enumerable: true
		, configurable: true
	};
	try {
		objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
	} catch (ex) { // IE 8 doesn't support enumerable:true
		if (ex.number === -0x7FF5EC54) {
			classListPropDesc.enumerable = false;
			objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
		}
	}
} else if (objCtr[protoProp].__defineGetter__) {
	elemCtrProto.__defineGetter__(classListProp, classListGetter);
}

}(self));

}</pre>
<h2 id="Browser_compatibility">Browser compatibility</h2>
<div>
  {{CompatibilityTable}}</div>
<div id="compat-desktop">
  <table class="compat-table">
    <tbody>
      <tr>
        <th>Feature</th>
        <th>Chrome</th>
        <th>Firefox (Gecko)</th>
        <th>Internet Explorer</th>
        <th>Opera</th>
        <th>Safari (WebKit)</th>
      </tr>
      <tr>
        <td>Basic support</td>
        <td>8.0</td>
        <td>{{ CompatGeckoDesktop("1.9.2") }}</td>
        <td>10</td>
        <td>11.50</td>
        <td>5.1<br />
          {{Webkitbug("20709")}}</td>
      </tr>
      <tr>
        <td>toggle method's second argument</td>
        <td>24</td>
        <td>{{CompatGeckoDesktop("24")}}</td>
        <td>no (IE 11 preview)</td>
        <td>15</td>
        <td>yes<br />
          {{Webkitbug("99375")}}
          <p>&nbsp;</p>
        </td>
      </tr>
    </tbody>
  </table>
</div>
<div id="compat-mobile">
  <table class="compat-table">
    <tbody>
      <tr>
        <th>Feature</th>
        <th>Android</th>
        <th>Firefox Mobile (Gecko)</th>
        <th>IE Phone</th>
        <th>Opera Mobile</th>
        <th>Safari Mobile</th>
      </tr>
      <tr>
        <td>Basic support</td>
        <td>3.0</td>
        <td><span style="line-height: 1.572;">{{CompatGeckoMobile("1.9.2")}}</span></td>
        <td>10</td>
        <td>11.10</td>
        <td>5.0</td>
      </tr>
      <tr>
        <td>toggle method's second argument</td>
        <td>?</td>
        <td>{{CompatGeckoMobile("24")}}</td>
        <td>?</td>
        <td>?</td>
        <td>?</td>
      </tr>
    </tbody>
  </table>
</div>
<h2 id="Specification">Specification</h2>
<ul>
  <li><a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-classlist" title="http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-classlist">http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-classlist</a></li>
  <li><a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#domtokenlist-0" title="http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#domtokenlist-0">http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#domtokenlist-0</a></li>
</ul>
<h2 id="See_also">See also</h2>
<ul>
  <li><a href="/en-US/docs/DOM/element.className" title="DOM/element.className">element.className</a></li>
</ul>
Revert to this revision