您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

classList.js 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. * classList.js: Cross-browser full element.classList implementation.
  3. * 1.1.20150312
  4. *
  5. * By Eli Grey, http://eligrey.com
  6. * License: Dedicated to the public domain.
  7. * See https://github.com/eligrey/classList.js/blob/master/LICENSE.md
  8. */
  9. /*global self, document, DOMException */
  10. /*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
  11. if ("document" in self) {
  12. // Full polyfill for browsers with no classList support
  13. if (!("classList" in document.createElement("_"))) {
  14. (function (view) {
  15. "use strict";
  16. if (!('Element' in view)) return;
  17. var
  18. classListProp = "classList"
  19. , protoProp = "prototype"
  20. , elemCtrProto = view.Element[protoProp]
  21. , objCtr = Object
  22. , strTrim = String[protoProp].trim || function () {
  23. return this.replace(/^\s+|\s+$/g, "");
  24. }
  25. , arrIndexOf = Array[protoProp].indexOf || function (item) {
  26. var
  27. i = 0
  28. , len = this.length
  29. ;
  30. for (; i < len; i++) {
  31. if (i in this && this[i] === item) {
  32. return i;
  33. }
  34. }
  35. return -1;
  36. }
  37. // Vendors: please allow content code to instantiate DOMExceptions
  38. , DOMEx = function (type, message) {
  39. this.name = type;
  40. this.code = DOMException[type];
  41. this.message = message;
  42. }
  43. , checkTokenAndGetIndex = function (classList, token) {
  44. if (token === "") {
  45. throw new DOMEx(
  46. "SYNTAX_ERR"
  47. , "An invalid or illegal string was specified"
  48. );
  49. }
  50. if (/\s/.test(token)) {
  51. throw new DOMEx(
  52. "INVALID_CHARACTER_ERR"
  53. , "String contains an invalid character"
  54. );
  55. }
  56. return arrIndexOf.call(classList, token);
  57. }
  58. , ClassList = function (elem) {
  59. var
  60. trimmedClasses = strTrim.call(elem.getAttribute("class") || "")
  61. , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
  62. , i = 0
  63. , len = classes.length
  64. ;
  65. for (; i < len; i++) {
  66. this.push(classes[i]);
  67. }
  68. this._updateClassName = function () {
  69. elem.setAttribute("class", this.toString());
  70. };
  71. }
  72. , classListProto = ClassList[protoProp] = []
  73. , classListGetter = function () {
  74. return new ClassList(this);
  75. }
  76. ;
  77. // Most DOMException implementations don't allow calling DOMException's toString()
  78. // on non-DOMExceptions. Error's toString() is sufficient here.
  79. DOMEx[protoProp] = Error[protoProp];
  80. classListProto.item = function (i) {
  81. return this[i] || null;
  82. };
  83. classListProto.contains = function (token) {
  84. token += "";
  85. return checkTokenAndGetIndex(this, token) !== -1;
  86. };
  87. classListProto.add = function () {
  88. var
  89. tokens = arguments
  90. , i = 0
  91. , l = tokens.length
  92. , token
  93. , updated = false
  94. ;
  95. do {
  96. token = tokens[i] + "";
  97. if (checkTokenAndGetIndex(this, token) === -1) {
  98. this.push(token);
  99. updated = true;
  100. }
  101. }
  102. while (++i < l);
  103. if (updated) {
  104. this._updateClassName();
  105. }
  106. };
  107. classListProto.remove = function () {
  108. var
  109. tokens = arguments
  110. , i = 0
  111. , l = tokens.length
  112. , token
  113. , updated = false
  114. , index
  115. ;
  116. do {
  117. token = tokens[i] + "";
  118. index = checkTokenAndGetIndex(this, token);
  119. while (index !== -1) {
  120. this.splice(index, 1);
  121. updated = true;
  122. index = checkTokenAndGetIndex(this, token);
  123. }
  124. }
  125. while (++i < l);
  126. if (updated) {
  127. this._updateClassName();
  128. }
  129. };
  130. classListProto.toggle = function (token, force) {
  131. token += "";
  132. var
  133. result = this.contains(token)
  134. , method = result ?
  135. force !== true && "remove"
  136. :
  137. force !== false && "add"
  138. ;
  139. if (method) {
  140. this[method](token);
  141. }
  142. if (force === true || force === false) {
  143. return force;
  144. } else {
  145. return !result;
  146. }
  147. };
  148. classListProto.toString = function () {
  149. return this.join(" ");
  150. };
  151. if (objCtr.defineProperty) {
  152. var classListPropDesc = {
  153. get: classListGetter
  154. , enumerable: true
  155. , configurable: true
  156. };
  157. try {
  158. objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
  159. } catch (ex) { // IE 8 doesn't support enumerable:true
  160. if (ex.number === -0x7FF5EC54) {
  161. classListPropDesc.enumerable = false;
  162. objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
  163. }
  164. }
  165. } else if (objCtr[protoProp].__defineGetter__) {
  166. elemCtrProto.__defineGetter__(classListProp, classListGetter);
  167. }
  168. }(self));
  169. } else {
  170. // There is full or partial native classList support, so just check if we need
  171. // to normalize the add/remove and toggle APIs.
  172. (function () {
  173. "use strict";
  174. var testElement = document.createElement("_");
  175. testElement.classList.add("c1", "c2");
  176. // Polyfill for IE 10/11 and Firefox <26, where classList.add and
  177. // classList.remove exist but support only one argument at a time.
  178. if (!testElement.classList.contains("c2")) {
  179. var createMethod = function(method) {
  180. var original = DOMTokenList.prototype[method];
  181. DOMTokenList.prototype[method] = function(token) {
  182. var i, len = arguments.length;
  183. for (i = 0; i < len; i++) {
  184. token = arguments[i];
  185. original.call(this, token);
  186. }
  187. };
  188. };
  189. createMethod('add');
  190. createMethod('remove');
  191. }
  192. testElement.classList.toggle("c3", false);
  193. // Polyfill for IE 10 and Firefox <24, where classList.toggle does not
  194. // support the second argument.
  195. if (testElement.classList.contains("c3")) {
  196. var _toggle = DOMTokenList.prototype.toggle;
  197. DOMTokenList.prototype.toggle = function(token, force) {
  198. if (1 in arguments && !this.contains(token) === !force) {
  199. return force;
  200. } else {
  201. return _toggle.call(this, token);
  202. }
  203. };
  204. }
  205. testElement = null;
  206. }());
  207. }
  208. }