兼容IE6+,因IE6、IE7、IE8不支持Array.prototype.indexOf()String.prototype.trim(),分别用Polyfill实现支持。

详细:

indexOf https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf

trimhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim

由于现代浏览器都基本支持了classList,所以移动端可以直接使用classList会更方便一些,如:

  1. <div class="foo bar" id="div"></div>
  2. var div = document.getElementById('div');
  3. div.classList.remove("foo");
  4. div.classList.add("anotherclass");
  5. div.classList.toggle("visible");
  6. div.classList.contains("foo"); //
  7. div.classList.add("foo","bar"); //Android4.3不支持
  1. 应该避免直接使用多个参数,支持不全面。
  2. SVGMathML 元素支持度也不全面(这个坑下面的代码并未填上,请熟知,有兴趣的可以查下Zepto是怎么填坑的)。

    classList支持明细: http://caniuse.com/#search=classList

代码

Polyfill

  1. // 让低版本IE支持 Array.prototype.indexOf
  2. // Polyfill (indexOf @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)
  3. if (!Array.prototype.indexOf) {
  4. Array.prototype.indexOf = function(searchElement, fromIndex) {
  5. var k;
  6. if (this == null) {
  7. throw new TypeError('"this" is null or not defined');
  8. }
  9. var o = Object(this);
  10. var len = o.length >>> 0;
  11. if (len === 0) {
  12. return -1;
  13. }
  14. var n = +fromIndex || 0;
  15. if (Math.abs(n) === Infinity) {
  16. n = 0;
  17. }
  18. if (n >= len) {
  19. return -1;
  20. }
  21. k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
  22. while (k < len) {
  23. if (k in o && o[k] === searchElement) {
  24. return k;
  25. }
  26. k++;
  27. }
  28. return -1;
  29. };
  30. }
  31. // 让低版本IE支持 String.prototype.trim()
  32. // Polyfill (trim @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim)
  33. if (!String.prototype.trim) {
  34. String.prototype.trim = function(){
  35. return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
  36. };
  37. }

支持 classList 实现方式

  1. function ctrlClass(opts) {
  2. if (!opts.ele || !opts.c) return false;
  3. // console.log(opts.c)
  4. var c = null;
  5. typeof (opts.c) === 'string' ?
  6. c = opts.c.trim().replace(/\s+/g, ' ').split(' ') :
  7. c = opts.c; //修复不规范传参
  8. return opts.fun({
  9. ele: opts.ele,
  10. c: c
  11. });
  12. opts.ele = null;
  13. }
  14. /**
  15. * hasClass
  16. * @param (element, 'c1 c2 c3 c4 c5')
  17. */
  18. function hasClass(ele, c) {
  19. return ctrlClass({
  20. ele: ele,
  21. c: c,
  22. fun: function(opts) {
  23. return opts.c.every(function(v) {
  24. return !!opts.ele.classList.contains(v);
  25. });
  26. }
  27. });
  28. }
  29. /**
  30. * addClass
  31. * @param (element, 'c1 c2 c3 c4 c5')
  32. */
  33. function addClass(ele, c) {
  34. return ctrlClass({
  35. ele: ele,
  36. c: c,
  37. fun: function(opts) {
  38. var ele = opts.ele,
  39. c = opts.c;
  40. c.forEach(function(v) {
  41. if (!hasClass(ele, v)) {
  42. ele.classList.add(v);
  43. }
  44. });
  45. }
  46. })
  47. }
  48. /**
  49. * removeClass
  50. * @param (element, 'c1 c2 c3')
  51. */
  52. function removeClass(ele, c) {
  53. ctrlClass({
  54. ele: ele,
  55. c: c,
  56. fun: function(opts) {
  57. var ele = opts.ele,
  58. c = opts.c;
  59. c.forEach(function(v) {
  60. // TODO 是否有必要判断 hasClass
  61. // if (!hasClass(ele, v)) {
  62. ele.classList.remove(v);
  63. // }
  64. });
  65. }
  66. });
  67. }
  68. /**
  69. * toggleClass
  70. * @param (element, 'c1 c2 c3')
  71. */
  72. function toggleClass(ele, c) {
  73. ctrlClass({
  74. ele: ele,
  75. c: c,
  76. fun: function(opts) {
  77. var ele = opts.ele,
  78. c = opts.c;
  79. c.forEach(function(v) {
  80. ele.classList.toggle(v);
  81. })
  82. }
  83. })
  84. }

不支持 classList 实现方式

  1. /**
  2. * hasClass
  3. * @param (element, 'c1 c2 c3 c4 c5')
  4. */
  5. function hasClass(ele, c) {
  6. return ctrlClass({
  7. ele: ele,
  8. c: c,
  9. fun: function(opts) {
  10. var cln = opts.ele.className.split(' ');
  11. var c = opts.c;
  12. for (var i = 0; i < c.length; i++) {
  13. if(cln.indexOf(c[i]) !== -1){
  14. return true;
  15. }
  16. }
  17. return false;
  18. }
  19. });
  20. }
  21. /**
  22. * addClass
  23. * @param (element, 'c1 c2 c3')
  24. */
  25. function addClass(ele, c) {
  26. ctrlClass({
  27. ele: ele,
  28. c: c,
  29. fun: function(opts) {
  30. var ele = opts.ele,
  31. c = opts.c;
  32. for (var i = 0; i < c.length; i++) {
  33. if(!hasClass(ele, c[i])) {
  34. ele.className = ele.className !== '' ? (ele.className + ' ' + c[i]) : c[i];
  35. }
  36. }
  37. }
  38. });
  39. }
  40. /**
  41. * removeClass
  42. * @param (element, 'c1 c2 c3')
  43. */
  44. function removeClass(ele, c) {
  45. ctrlClass({
  46. ele: ele,
  47. c: c,
  48. fun: function(opts) {
  49. var ele = opts.ele,
  50. c = opts.c,
  51. cln = ele.className.split(' ');
  52. for (var i = 0; i < c.length; i++) {
  53. if (hasClass(ele, c[i])) {
  54. cln.splice(cln.indexOf(c[i]), 1);
  55. }
  56. }
  57. ele.className = cln.join(' ');
  58. }
  59. });
  60. }
  61. /**
  62. * toggleClass
  63. * @param (element, 'c1 c2 c3')
  64. */
  65. function toggleClass(ele, c){
  66. ctrlClass({
  67. ele: ele,
  68. c: c,
  69. fun: function(opts) {
  70. var ele = opts.ele,
  71. c = opts.c;
  72. for (var i = 0; i < c.length; i++) {
  73. !!hasClass(ele, c[i]) ? removeClass(ele, c[i]) : addClass(ele, c[i]);
  74. }
  75. }
  76. });
  77. }

完整代码

  1. // Polyfill (indexOf @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)
  2. if (!Array.prototype.indexOf) {
  3. Array.prototype.indexOf = function(searchElement, fromIndex) {
  4. var k;
  5. if (this == null) {
  6. throw new TypeError('"this" is null or not defined');
  7. }
  8. var o = Object(this);
  9. var len = o.length >>> 0;
  10. if (len === 0) {
  11. return -1;
  12. }
  13. var n = +fromIndex || 0;
  14. if (Math.abs(n) === Infinity) {
  15. n = 0;
  16. }
  17. if (n >= len) {
  18. return -1;
  19. }
  20. k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
  21. while (k < len) {
  22. if (k in o && o[k] === searchElement) {
  23. return k;
  24. }
  25. k++;
  26. }
  27. return -1;
  28. };
  29. }
  30. // Polyfill (trim @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim)
  31. if (!String.prototype.trim) {
  32. String.prototype.trim = function(){
  33. return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
  34. };
  35. }
  36. var cl = ('classList' in document.createElement('a'));
  37. function ctrlClass(opts) {
  38. if (!opts.ele || !opts.c) return false;
  39. // console.log(opts.c)
  40. var c = null;
  41. typeof (opts.c) === 'string' ?
  42. c = opts.c.trim().replace(/\s+/g, ' ').split(' ') :
  43. c = opts.c; //修复不规范传参
  44. return opts.fun({
  45. ele: opts.ele,
  46. c: c
  47. });
  48. opts.ele = null;
  49. }
  50. // 支持 classList
  51. if(cl){
  52. /**
  53. * hasClass
  54. * @param (element, 'c1 c2 c3 c4 c5')
  55. */
  56. function hasClass(ele, c) {
  57. return ctrlClass({
  58. ele: ele,
  59. c: c,
  60. fun: function(opts) {
  61. return opts.c.every(function(v) {
  62. return !!opts.ele.classList.contains(v);
  63. });
  64. }
  65. });
  66. }
  67. /**
  68. * addClass
  69. * @param (element, 'c1 c2 c3 c4 c5')
  70. */
  71. function addClass(ele, c) {
  72. return ctrlClass({
  73. ele: ele,
  74. c: c,
  75. fun: function(opts) {
  76. var ele = opts.ele,
  77. c = opts.c;
  78. c.forEach(function(v) {
  79. if (!hasClass(ele, v)) {
  80. ele.classList.add(v);
  81. }
  82. });
  83. }
  84. })
  85. }
  86. /**
  87. * removeClass
  88. * @param (element, 'c1 c2 c3')
  89. */
  90. function removeClass(ele, c) {
  91. ctrlClass({
  92. ele: ele,
  93. c: c,
  94. fun: function(opts) {
  95. var ele = opts.ele,
  96. c = opts.c;
  97. c.forEach(function(v) {
  98. // TODO 是否有必要判断 hasClass
  99. // if (!hasClass(ele, v)) {
  100. ele.classList.remove(v);
  101. // }
  102. });
  103. }
  104. });
  105. }
  106. /**
  107. * toggleClass
  108. * @param (element, 'c1 c2 c3')
  109. */
  110. function toggleClass(ele, c) {
  111. ctrlClass({
  112. ele: ele,
  113. c: c,
  114. fun: function(opts) {
  115. var ele = opts.ele,
  116. c = opts.c;
  117. c.forEach(function(v) {
  118. ele.classList.toggle(v);
  119. })
  120. }
  121. })
  122. }
  123. }else{
  124. /**
  125. * hasClass
  126. * @param (element, 'c1 c2 c3 c4 c5')
  127. */
  128. function hasClass(ele, c) {
  129. return ctrlClass({
  130. ele: ele,
  131. c: c,
  132. fun: function(opts) {
  133. var cln = opts.ele.className.split(' ');
  134. var c = opts.c;
  135. for (var i = 0; i < c.length; i++) {
  136. if(cln.indexOf(c[i]) !== -1){
  137. return true;
  138. }
  139. }
  140. return false;
  141. }
  142. });
  143. }
  144. /**
  145. * addClass
  146. * @param (element, 'c1 c2 c3')
  147. */
  148. function addClass(ele, c) {
  149. ctrlClass({
  150. ele: ele,
  151. c: c,
  152. fun: function(opts) {
  153. var ele = opts.ele,
  154. c = opts.c;
  155. for (var i = 0; i < c.length; i++) {
  156. if(!hasClass(ele, c[i])) {
  157. ele.className = ele.className !== '' ? (ele.className + ' ' + c[i]) : c[i];
  158. }
  159. }
  160. }
  161. });
  162. }
  163. /**
  164. * removeClass
  165. * @param (element, 'c1 c2 c3')
  166. */
  167. function removeClass(ele, c) {
  168. ctrlClass({
  169. ele: ele,
  170. c: c,
  171. fun: function(opts) {
  172. var ele = opts.ele,
  173. c = opts.c,
  174. cln = ele.className.split(' ');
  175. for (var i = 0; i < c.length; i++) {
  176. if (hasClass(ele, c[i])) {
  177. cln.splice(cln.indexOf(c[i]), 1);
  178. }
  179. }
  180. ele.className = cln.join(' ');
  181. }
  182. });
  183. }
  184. /**
  185. * toggleClass
  186. * @param (element, 'c1 c2 c3')
  187. */
  188. function toggleClass(ele, c){
  189. ctrlClass({
  190. ele: ele,
  191. c: c,
  192. fun: function(opts) {
  193. var ele = opts.ele,
  194. c = opts.c;
  195. for (var i = 0; i < c.length; i++) {
  196. !!hasClass(ele, c[i]) ? removeClass(ele, c[i]) : addClass(ele, c[i]);
  197. }
  198. }
  199. });
  200. }
  201. }

使用

  1. var ele = document.getElementById('test');
  2. hasClass(ele, 'c1');
  3. addClass(ele, 'c1 c2 c3');
  4. removeClass(ele, 'c1 c2 c3');
  5. toggleClass(ele, 'c1 c2 c3');

项目

https://github.com/givebest/ctrl-cssClass

原生JavaScript实现hasClass、addClass、removeClass、toggleClass的更多相关文章

  1. 原生JavaScript实现的addclass,removeclass,hasclass,toggleclass,getbyclass

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  2. jQuery addClass removeClass toggleClass hasClass is(.class)用法

    jQuery addClass removeClass toggleClass hasClass is(.class)用法 <%@ page language="java" ...

  3. 原生JS实现addClass,removeClass,toggleClass

    jQuery操作class的方式非常强大,但是目前还有一些人不知道如何使用或者由于项目统一性的原因无法使用jquery. 在此写了一个利用原生js来实现对dom元素class的操作方法 1.addCl ...

  4. 原声js实现addClass removeClass toggleClass效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. Jquery重新学习之三[属性addClass(),removeClass(),toggleClass()]

    1:属性.addClass(class|fn)及.removeClass(class|fn) 1.1 .addClass(class) 参数class一个或多个要添加到元素中的CSS类名,请用空格分开 ...

  6. addClass, removeClass, toggleClass(从jquery中抠出来)

    <div id="d3" class="cur"></div> var mylibs = (function(){ var rtrim ...

  7. class 添加样式,删,开关 【选择】addClass,removeClass,toggleClass

    <1> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>< ...

  8. class 添加样式,删除,开关 【选择】addClass,removeClass,toggleClass

    <1> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>< ...

  9. .addClass(),.removeClass(),.toggleClass()的区别

    .addClass("className")方法是用来给指定元素增加类名,也就是说给指定的元素追加样式: 可以同时添加多个类名,空格符隔开 $("selector&quo ...

随机推荐

  1. Laravel Composer and ServiceProvider

    Composer and: 创建自定义类库时,按命名空间把文件夹结构组织好 composer.json>autoload>classmap>psr-4 composer dump-a ...

  2. 【原】AFNetworking源码阅读(三)

    [原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...

  3. 6. ModelDriven拦截器、Preparable 拦截器

    1. 问题 Struts2 的 Action 我们将它定义为一个控制器,但是由于在 Action 中也可以来编写一些业务逻辑,也有人会在 Action 输入业务逻辑层. 但是在企业开发中,我们一般会将 ...

  4. C#多线程之基础篇3

    在上一篇C#多线程之基础篇2中,我们主要讲述了确定线程的状态.线程优先级.前台线程和后台线程以及向线程传递参数的知识,在这一篇中我们将讲述如何使用C#的lock关键字锁定线程.使用Monitor锁定线 ...

  5. Shell碎碎念

    1. 字符串如何大小写转换 str="This is a Bash Shell script." 1> tr方式 newstr=`tr '[A-Z]' '[a-z]' < ...

  6. Linux杀死进程,查看进程

    http://blog.csdn.net/wojiaopanpan/article/details/7286430/

  7. UML图中经常用到几种的关系图例

    学习这个东西挺奇怪的,时间一长就容易忘记,或者记不清楚.今天看到一些UML图的关系,发现有些出入了,索性就写下来,以后再忘记的时候过来看看. 在UML的类图中,常见的有以下几种关系: 继承(Gener ...

  8. RabbitMQ + PHP (二)AMQP拓展安装

    上篇说到了 RabbitMQ 的安装. 这次要在讲案例之前,需要安装PHP的AMQP扩展.不然可能会报以下两个错误. 1.Fatal error: Class 'AMQPConnection' not ...

  9. webpack学习总结

    前言 在还未接触webpack,就有几个疑问: 1. webpack本质上是什么? 2. 跟异步模块加载有关系吗? 3. 可否生成多个文件,一定是一个? 4. 被引用的文件有其他异步加载模块怎么办? ...

  10. Atitit.项目修改补丁打包工具 使用说明

    Atitit.项目修改补丁打包工具 使用说明 1.1. 打包工具已经在群里面.打包工具.bat1 1.2. 使用方法:放在项目主目录下,执行即可1 1.3. 打包工具的原理以及要打包的项目列表1 1. ...