Join MDN and developers like you at Mozilla's View Source conference, 12-14 September in Berlin, Germany. Learn more at https://viewsourceconf.org

Element.classList

这篇文章需要文法复核。如何帮忙。

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, 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 ("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.

 

相关链接

文档标签和贡献者

 此页面的贡献者: NarK, teoli, AlexChao, ziyunfei, Wladimir_Palant
 最后编辑者: NarK,