这篇文章需要文法复核。如何帮忙。
Element.classList 是一个只读属性,返回一个 DOMTokenList,其中包含元素所有现有的 class 属性。
使用 classList 要比 element.className 方便不少,后者是一个用空格分隔的字符串。
语法
var elementClasses = elementNodeReference.classList;
elementClasses 是一个 DOMTokenList ,代表 elementNodeReference 的 class 属性 。如果没有 class 属性或为空,则 elementClasses.length 返回 0。element.classList 本身是只读的,但可以使用 add() 和 remove() 方法修改它。
方法
- add( String [, String] )
- 添加给定的 class 。元素已有的 class 会被忽略。
- remove( String [,String] )
- 移除给定的 class 。
- item ( Number )
- 根据索引位置,返回 class 值。
- toggle ( String [, force] )
- 仅传一个参数时:切换 class 属性。亦即,当该 class 存在时移除并返回 false,否则增加该 class 并返回 true。
传入第二个参数时:若第二个参数为 true 则增加该 class,若为 false 则移除。 - contains( String )
- 检查元素是否拥有给定的 class。
示例
// div 是一个 <div> 元素的对象引用,拥有 class="foo bar"
div.classList.remove("foo");
div.classList.add("anotherclass");
// 如果存在 visible,则移除,否则添加
div.classList.toggle("visible");
// 增加或删除 visible,取决于条件 i < 10 的取值结果
div.classList.toggle("visible", i < 10);
alert(div.classList.contains("foo"));
div.classList.add("foo","bar"); //添加多个 class
Firefox 26 以下的版本并未实现 add/remove/toggle 方法中的所有参数。参见 https://bugzilla.mozilla.org/show_bug.cgi?id=814014
跨浏览器 JavaScript shim
注意:该 shim实现 在 IE 8 以下不起作用。
/*
* classList.js: Cross-browser full element.classList implementation.
* 2014-07-23
*
* 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 ("document" in self) {
// Full polyfill for browsers with no classList support
if (!("classList" in document.createElement("_"))) {
(function (view) {
"use strict";
if (!('Element' in view)) return;
var
classListProp = "classList"
, protoProp = "prototype"
, elemCtrProto = 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.getAttribute("class") || "")
, classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
, i = 0
, len = classes.length
;
for (; i < len; i++) {
this.push(classes[i]);
}
this._updateClassName = function () {
elem.setAttribute("class", 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
, index
;
do {
token = tokens[i] + "";
index = checkTokenAndGetIndex(this, token);
while (index !== -1) {
this.splice(index, 1);
updated = true;
index = checkTokenAndGetIndex(this, token);
}
}
while (++i < l);
if (updated) {
this._updateClassName();
}
};
classListProto.toggle = function (token, force) {
token += "";
var
result = this.contains(token)
, method = result ?
force !== true && "remove"
:
force !== false && "add"
;
if (method) {
this[method](token);
}
if (force === true || force === false) {
return force;
} else {
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));
} else {
// There is full or partial native classList support, so just check if we need
// to normalize the add/remove and toggle APIs.
(function () {
"use strict";
var testElement = document.createElement("_");
testElement.classList.add("c1", "c2");
// Polyfill for IE 10/11 and Firefox <26, where classList.add and
// classList.remove exist but support only one argument at a time.
if (!testElement.classList.contains("c2")) {
var createMethod = function(method) {
var original = DOMTokenList.prototype[method];
DOMTokenList.prototype[method] = function(token) {
var i, len = arguments.length;
for (i = 0; i < len; i++) {
token = arguments[i];
original.call(this, token);
}
};
};
createMethod('add');
createMethod('remove');
}
testElement.classList.toggle("c3", false);
// Polyfill for IE 10 and Firefox <24, where classList.toggle does not
// support the second argument.
if (testElement.classList.contains("c3")) {
var _toggle = DOMTokenList.prototype.toggle;
DOMTokenList.prototype.toggle = function(token, force) {
if (1 in arguments && !this.contains(token) === !force) {
return force;
} else {
return _toggle.call(this, token);
}
};
}
testElement = null;
}());
}
}
规范
| Specification | Status | Comment |
|---|---|---|
| WHATWG HTML Living Standard Element.classList |
Living Standard | Note within the HTML specification related to the class attribute. |
| DOM Element.classList |
Living Standard | Initial definition |
| DOM4 Element.classList |
Recommendation |
浏览器兼容性
| Feature | Chrome | Edge | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
|---|---|---|---|---|---|---|
| Basic support | 8.0 | (Yes) | 3.6 (1.9.2) | 10[1] | 11.50 | 5.1 |
| toggle method's second argument | 24 | (Yes) | 24 (24) | 未实现[2] | 15 | 5.1 |
| Feature | Android | Firefox Mobile (Gecko) | IE Phone | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|
| Basic support | 3.0 | 1.0 (1.9.2) | 10 | 11.10 | 5.0 |
| toggle method's second argument | ? | 24.0 (24) | ? | ? | ? |
[1] Not supported for SVG elements. See a report at Microsoft about that.
[2] Internet Explorer never implemented this. See a report at Microsoft about that.