【需求描述】:
<div id="div1" class="class1">div>
Jquery 中 addClass 与 removeClass 是两个使用高频的方法,对于为 dom 元素增删 class 类非常方便。
$("#div1").addClass("class2");
$("#div1").removeClass("class1");
我们随便获取一个dom对象,打印(console.dir()
)出它的对象属性,可以看到管理 class 类的主要有 classList 属性与 className 属性。
classList 属性的值为 DOMTokenList 对象,关于DOMTokenList官方解释是一组空格分隔的标记,与Array一样具有 length 属性,且索引从0开始,但无法使用 Array 对象的方法。
不过 DOMTokenList 对象内置了 add,remove,contains 等方法,用于增删改查等操作;所以我们可以使用add,remove 像JQ中 addClass 与 removeClass 方法一样操作 class 类。
let div = document.getElementById('div1');
div.classList.add("class2");
div.classList.remove("class1");
我们发现这两个方法用的很爽啊,跟JQ一样,一个方法解决class类的操作,但比较遗憾的是,这两个方法均存在兼容问题:
虽然其它浏览器兼容性良好,但铁打的IE从9之前完全不支持classList属性,从版本10开始支持该属性,但不支持 add 与 remove 方法。
所以说如果要兼容IE,此做法不可取,但如果不用考虑IE,那就真的能像JQ一样使用便捷了。
说完 classList 属性,我们再考虑从 className 下手;className 属性与 classList 属性同为 Dom 属性且都管理 class 类的值,不同的是 classLis t属性值为特殊的 DOMTokenList 对象,而 className 属性的值为普通的字符串。
我们尝试自定义一个有class类的元素,分别获取两者的值:
<div id="div1" class="demo1 demo2">div>
那要从 className 属性入手来操作class类,无非就是字符串的拼接截取操作了,这里就直接附上代码:
//自定义添加class方法
function addClass(ele, name) {
if (name) {
//判断该dom有没有class,有则在原class基础上增加,无则直接赋值
ele.className ? ele.className = ele.className + " " + name : ele.className = name;
} else {
throw new Error("请传递一个有效的class类名");
};
};
//自定义删除class类方法
function removeClass(ele, name) {
//将className属性转为数组
let classArr = ele.className.split(" "),
index = classArr.indexOf(name);
//将符合条件的class类删除
index > -1 ? classArr.splice(index, 1) : null;
ele.className = classArr.join(" ");
};
let div = document.getElementById('div1');
//测试调用
addClass(div, 'demo1');
removeClass(div, 'demo1');
const divDoc = document.getElementById('div1')
let classVal = divDoc.getAttribute('class')
// 删除class1
classVal = classVal.replace('class1', '')
divDoc.setAttribute('class', classVal)
// 添加class2
classVal = classVal.concat(' class1')
divDoc.setAttribute('class', classVal)
// 用class2代替class1
classVal = classVal.replace('class1', 'class2')
divDoc.setAttribute('class', classVal)
function hasClass(elem, cls) {
cls = cls || ''
if (cls.replace(/\s/g, '').length === 0) return false //当cls没有参数时,返回false
return new RegExp(' ' + cls + ' ').test(' ' + elem.className + ' ')
}
function addClass(elem, cls) {
if (!hasClass(elem, cls)) {
elem.className = elem.className === '' ? cls : elem.className + ' ' + cls
}
}
function removeClass(elem, cls) {
if (hasClass(elem, cls)) {
var newClass = ' ' + elem.className.replace(/[\t\r\n]/g, '') + ' '
while (newClass.indexOf(' ' + cls + ' ') >= 0) {
newClass = newClass.replace(' ' + cls + ' ', ' ')
}
elem.className = newClass.replace(/^\s+|\s+$/g, '')
}
}
测试:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>引入jstitle>
head>
<body>
<div id="div1" class="class1">div>
body>
<script src="add-class.js">script>
<script>
const divDoc = document.getElementById('div1')
console.log('div1 has class1: ', hasClass(divDoc, 'class1'))
console.log('div1 has class2: ', hasClass(divDoc, 'class2'))
addClass(divDoc, 'class2')
console.log('after addClass, div1 has class2: ', hasClass(divDoc, 'class2'))
removeClass(divDoc, 'class1')
console.log('after removeClass, div1 has class1: ', hasClass(divDoc, 'class1'))
script>
html>
// obj为节点对象,eg: document.getElementById('div')
function hasClass(obj, cls) {
var obj_class = obj.className, //获取 class 内容.
obj_class_lst = obj_class.split(/\s+/) //通过split空字符将cls转换成数组.
var x = 0
for (x in obj_class_lst) {
if (obj_class_lst[x] === cls) {//循环数组, 判断是否包含cls
return true
}
}
return false
}
function addClass(obj, cls) {
var obj_class = obj.className, //获取 class 内容.
blank = (obj_class !== '') ? ' ' : '' //判断获取到的 class 是否为空, 如果不为空在前面加个'空格'.
var added = obj_class + blank + cls //组合原来的 class 和需要添加的 class.
obj.className = added //替换原来的 class.
}
function removeClass(obj, cls) {
var obj_class = ' ' + obj.className + ' ' //获取 class 内容, 并在首尾各加一个空格. ex) 'abc bcd' -> ' abc bcd '
obj_class = obj_class.replace(/(\s+)/gi, ' ') //将多余的空字符替换成一个空格. ex) ' abc bcd ' -> ' abc bcd '
var removed = obj_class.replace(' ' + cls + ' ', ' ') //在原来的 class 替换掉首尾加了空格的 class. ex) ' abc bcd ' -> 'bcd '
removed = removed.replace(/(^\s+)|(\s+$)/g, '') //去掉首尾空格. ex) 'bcd ' -> 'bcd'
obj.className = removed//替换原来的 class.
}
以上就是全部总结啦,在项目中我们可以根据自己的需求酌情使用。
如果你觉得这篇文章有用,动动小手给我点个赞吧