原生JavaScript实现hasClass、addClass、removeClass、toggleClass
兼容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
trim: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim
由于现代浏览器都基本支持了classList,所以移动端可以直接使用classList会更方便一些,如:
<div class="foo bar" id="div"></div>
var div = document.getElementById('div');
div.classList.remove("foo");
div.classList.add("anotherclass");
div.classList.toggle("visible");
div.classList.contains("foo"); //
div.classList.add("foo","bar"); //Android4.3不支持
- 应该避免直接使用多个参数,支持不全面。
SVG和MathML元素支持度也不全面(这个坑下面的代码并未填上,请熟知,有兴趣的可以查下Zepto是怎么填坑的)。
classList支持明细: http://caniuse.com/#search=classList
代码
Polyfill
// 让低版本IE支持 Array.prototype.indexOf
// Polyfill (indexOf @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement, fromIndex) {
var k;
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
var len = o.length >>> 0;
if (len === 0) {
return -1;
}
var n = +fromIndex || 0;
if (Math.abs(n) === Infinity) {
n = 0;
}
if (n >= len) {
return -1;
}
k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
while (k < len) {
if (k in o && o[k] === searchElement) {
return k;
}
k++;
}
return -1;
};
}
// 让低版本IE支持 String.prototype.trim()
// Polyfill (trim @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim)
if (!String.prototype.trim) {
String.prototype.trim = function(){
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
};
}
支持 classList 实现方式
function ctrlClass(opts) {
if (!opts.ele || !opts.c) return false;
// console.log(opts.c)
var c = null;
typeof (opts.c) === 'string' ?
c = opts.c.trim().replace(/\s+/g, ' ').split(' ') :
c = opts.c; //修复不规范传参
return opts.fun({
ele: opts.ele,
c: c
});
opts.ele = null;
}
/**
* hasClass
* @param (element, 'c1 c2 c3 c4 c5')
*/
function hasClass(ele, c) {
return ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
return opts.c.every(function(v) {
return !!opts.ele.classList.contains(v);
});
}
});
}
/**
* addClass
* @param (element, 'c1 c2 c3 c4 c5')
*/
function addClass(ele, c) {
return ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var ele = opts.ele,
c = opts.c;
c.forEach(function(v) {
if (!hasClass(ele, v)) {
ele.classList.add(v);
}
});
}
})
}
/**
* removeClass
* @param (element, 'c1 c2 c3')
*/
function removeClass(ele, c) {
ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var ele = opts.ele,
c = opts.c;
c.forEach(function(v) {
// TODO 是否有必要判断 hasClass
// if (!hasClass(ele, v)) {
ele.classList.remove(v);
// }
});
}
});
}
/**
* toggleClass
* @param (element, 'c1 c2 c3')
*/
function toggleClass(ele, c) {
ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var ele = opts.ele,
c = opts.c;
c.forEach(function(v) {
ele.classList.toggle(v);
})
}
})
}
不支持 classList 实现方式
/**
* hasClass
* @param (element, 'c1 c2 c3 c4 c5')
*/
function hasClass(ele, c) {
return ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var cln = opts.ele.className.split(' ');
var c = opts.c;
for (var i = 0; i < c.length; i++) {
if(cln.indexOf(c[i]) !== -1){
return true;
}
}
return false;
}
});
}
/**
* addClass
* @param (element, 'c1 c2 c3')
*/
function addClass(ele, c) {
ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var ele = opts.ele,
c = opts.c;
for (var i = 0; i < c.length; i++) {
if(!hasClass(ele, c[i])) {
ele.className = ele.className !== '' ? (ele.className + ' ' + c[i]) : c[i];
}
}
}
});
}
/**
* removeClass
* @param (element, 'c1 c2 c3')
*/
function removeClass(ele, c) {
ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var ele = opts.ele,
c = opts.c,
cln = ele.className.split(' ');
for (var i = 0; i < c.length; i++) {
if (hasClass(ele, c[i])) {
cln.splice(cln.indexOf(c[i]), 1);
}
}
ele.className = cln.join(' ');
}
});
}
/**
* toggleClass
* @param (element, 'c1 c2 c3')
*/
function toggleClass(ele, c){
ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var ele = opts.ele,
c = opts.c;
for (var i = 0; i < c.length; i++) {
!!hasClass(ele, c[i]) ? removeClass(ele, c[i]) : addClass(ele, c[i]);
}
}
});
}
完整代码
// Polyfill (indexOf @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement, fromIndex) {
var k;
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
var len = o.length >>> 0;
if (len === 0) {
return -1;
}
var n = +fromIndex || 0;
if (Math.abs(n) === Infinity) {
n = 0;
}
if (n >= len) {
return -1;
}
k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
while (k < len) {
if (k in o && o[k] === searchElement) {
return k;
}
k++;
}
return -1;
};
}
// Polyfill (trim @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim)
if (!String.prototype.trim) {
String.prototype.trim = function(){
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
};
}
var cl = ('classList' in document.createElement('a'));
function ctrlClass(opts) {
if (!opts.ele || !opts.c) return false;
// console.log(opts.c)
var c = null;
typeof (opts.c) === 'string' ?
c = opts.c.trim().replace(/\s+/g, ' ').split(' ') :
c = opts.c; //修复不规范传参
return opts.fun({
ele: opts.ele,
c: c
});
opts.ele = null;
}
// 支持 classList
if(cl){
/**
* hasClass
* @param (element, 'c1 c2 c3 c4 c5')
*/
function hasClass(ele, c) {
return ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
return opts.c.every(function(v) {
return !!opts.ele.classList.contains(v);
});
}
});
}
/**
* addClass
* @param (element, 'c1 c2 c3 c4 c5')
*/
function addClass(ele, c) {
return ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var ele = opts.ele,
c = opts.c;
c.forEach(function(v) {
if (!hasClass(ele, v)) {
ele.classList.add(v);
}
});
}
})
}
/**
* removeClass
* @param (element, 'c1 c2 c3')
*/
function removeClass(ele, c) {
ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var ele = opts.ele,
c = opts.c;
c.forEach(function(v) {
// TODO 是否有必要判断 hasClass
// if (!hasClass(ele, v)) {
ele.classList.remove(v);
// }
});
}
});
}
/**
* toggleClass
* @param (element, 'c1 c2 c3')
*/
function toggleClass(ele, c) {
ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var ele = opts.ele,
c = opts.c;
c.forEach(function(v) {
ele.classList.toggle(v);
})
}
})
}
}else{
/**
* hasClass
* @param (element, 'c1 c2 c3 c4 c5')
*/
function hasClass(ele, c) {
return ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var cln = opts.ele.className.split(' ');
var c = opts.c;
for (var i = 0; i < c.length; i++) {
if(cln.indexOf(c[i]) !== -1){
return true;
}
}
return false;
}
});
}
/**
* addClass
* @param (element, 'c1 c2 c3')
*/
function addClass(ele, c) {
ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var ele = opts.ele,
c = opts.c;
for (var i = 0; i < c.length; i++) {
if(!hasClass(ele, c[i])) {
ele.className = ele.className !== '' ? (ele.className + ' ' + c[i]) : c[i];
}
}
}
});
}
/**
* removeClass
* @param (element, 'c1 c2 c3')
*/
function removeClass(ele, c) {
ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var ele = opts.ele,
c = opts.c,
cln = ele.className.split(' ');
for (var i = 0; i < c.length; i++) {
if (hasClass(ele, c[i])) {
cln.splice(cln.indexOf(c[i]), 1);
}
}
ele.className = cln.join(' ');
}
});
}
/**
* toggleClass
* @param (element, 'c1 c2 c3')
*/
function toggleClass(ele, c){
ctrlClass({
ele: ele,
c: c,
fun: function(opts) {
var ele = opts.ele,
c = opts.c;
for (var i = 0; i < c.length; i++) {
!!hasClass(ele, c[i]) ? removeClass(ele, c[i]) : addClass(ele, c[i]);
}
}
});
}
}
使用
var ele = document.getElementById('test');
hasClass(ele, 'c1');
addClass(ele, 'c1 c2 c3');
removeClass(ele, 'c1 c2 c3');
toggleClass(ele, 'c1 c2 c3');
项目
https://github.com/givebest/ctrl-cssClass
原生JavaScript实现hasClass、addClass、removeClass、toggleClass的更多相关文章
- 原生JavaScript实现的addclass,removeclass,hasclass,toggleclass,getbyclass
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- jQuery addClass removeClass toggleClass hasClass is(.class)用法
jQuery addClass removeClass toggleClass hasClass is(.class)用法 <%@ page language="java" ...
- 原生JS实现addClass,removeClass,toggleClass
jQuery操作class的方式非常强大,但是目前还有一些人不知道如何使用或者由于项目统一性的原因无法使用jquery. 在此写了一个利用原生js来实现对dom元素class的操作方法 1.addCl ...
- 原声js实现addClass removeClass toggleClass效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Jquery重新学习之三[属性addClass(),removeClass(),toggleClass()]
1:属性.addClass(class|fn)及.removeClass(class|fn) 1.1 .addClass(class) 参数class一个或多个要添加到元素中的CSS类名,请用空格分开 ...
- addClass, removeClass, toggleClass(从jquery中抠出来)
<div id="d3" class="cur"></div> var mylibs = (function(){ var rtrim ...
- class 添加样式,删,开关 【选择】addClass,removeClass,toggleClass
<1> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>< ...
- class 添加样式,删除,开关 【选择】addClass,removeClass,toggleClass
<1> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>< ...
- .addClass(),.removeClass(),.toggleClass()的区别
.addClass("className")方法是用来给指定元素增加类名,也就是说给指定的元素追加样式: 可以同时添加多个类名,空格符隔开 $("selector&quo ...
随机推荐
- react-router 组件式配置与对象式配置小区别
1. react-router 对象式配置 和 组件式配置 组件式配置(Redirect) ----对应---- 对象式配置(onEnter钩子) IndexRedirect -----对应-- ...
- 前端CSS预处理器Sass
前面的话 "CSS预处理器"(css preprocessor)的基本思想是,用一种专门的编程语言,进行网页样式设计,然后再编译成正常的CSS文件.SASS是一种CSS的开发工 ...
- 透过WinDBG的视角看String
摘要 : 最近在博客园里面看到有人在讨论 C# String的一些特性. 大部分情况下是从CODING的角度来讨论String. 本人觉得非常好奇, 在运行时态, String是如何与这些特性联系上的 ...
- .NET 对接JAVA 使用Modulus,Exponent RSA 加密
最近有一个工作是需要把数据用RSA发送给Java 虽然一开始标准公钥 net和Java RSA填充的一些算法不一样 但是后来这个坑也补的差不多了 具体可以参考 http://www.cnblogs. ...
- "无法删除数据库,因为该数据库当前正在使用"问题解决
异常处理汇总-数据库系列 http://www.cnblogs.com/dunitian/p/4522990.html 以前刚学数据库的时候比较苦恼这个问题,今天删除的时候又看见了,正好一起记录一下 ...
- 玩转spring boot——结合JPA入门
参考官方例子:https://spring.io/guides/gs/accessing-data-jpa/ 接着上篇内容 一.小试牛刀 创建maven项目后,修改pom.xml文件 <proj ...
- 用django创建一个项目
首先你得安装好python和django,然后配置好环境变量,安装python就不说了,从配置环境变量开始 1.配置环境变量 在我的电脑处点击右键,或者打开 控制面板\系统和安全\系统 -> 左 ...
- 每天一个设计模式-7 生成器模式(Builder)
每天一个设计模式-7 生成器模式(Builder) 一.实际问题 在讨论工厂方法模式的时候,提到了一个导出数据的应用框架,但是并没有涉及到导出数据的具体实现,这次通过生成器模式来简单实现导出成文本,X ...
- BPM始终服务于人,落脚于人
数字经济时代下,云计算.大数据.移动互联已经成为当下企业必须采取的武装力量.随着互联网+.中国制造2025.工业4.0等国家战略的引导与支持,无数的企业在这场数字化浪潮中使尽浑身解数,想要抓住机遇奋力 ...
- [转]ThinkPHP中实例化对象M()和D()的区别,select和find的区别
1.ThinkPHP中实例化对象M()和D()的区别 在实例化的过程中,经常使用D方法和M方法,这两个方法的区别在于M方法实例化模型无需用户为每个数据表定义模型类,如果D方法没有找到定义的模型类,则会 ...