概要
classList は、要素の class 属性のトークンリストを返します。
element.className でスペースで区切られた要素のクラス文字列にアクセスする方法もありますが、 classList はより便利な代替手段となります。以下の様な一般的なタスクを簡単に実行することができます。
- add: 要素のクラスリストへのクラスの追加
- remove: 要素のクラスリストからのクラスの削除
- toggle: 要素のクラスリスト中の特定のクラスの切替
- contains: 要素のクラスリストが特定のクラスを含むか否かの確認
構文
var elementClasses = elementNodeReference.classList;
elementClasses は、elementNodeReference の class 属性を提供する DOMTokenList です。class 属性がない場合または空の場合、elementClasses.length は 0 を返します。element.classList は読取専用です。
例
// div は、class="foo bar" を持つ <div> 要素を参照するオブジェクトです
div.classList.remove("foo");
div.classList.add("anotherclass");
// class に visible が設定されている場合は削除し、それ以外の場合は追加します
div.classList.toggle("visible");
alert( div.classList.contains("foo") );
他の実装の為の JavaScript shim
注意: このシムは Internet Explorer 7 以下では動作しません。
/*
* classList.js: Cross-browser full element.classList implementation.
* 2012-11-15
*
* By Eli Grey, https://eligrey.com
* Public Domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/
/*global self, document, DOMException */
/*! @source https://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) {
(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));
}
ブラウザ実装状況
| 機能 | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
|---|---|---|---|---|---|
| 基本サポート | 8.0 | 3.6 (1.9.2) バグ 501257 |
10 | Opera 11.50 | 5.1 WebKit bug 20709 |
| 機能 | Android | Firefox Mobile (Gecko) | IE Phone | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|
| 基本サポート | 3.0 | 1.0 (1.9.2) | 未サポート | 11.10 | 5.0 |
仕様書
- https://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-classlist
- https://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#domtokenlist-0
関連情報
- Bug 501257 - Implement HTML 5's HTMLElement.classList property