可以用setAttribute/removeAttribute对类名进行增删操作吗?

在群里讨论原生js对类名的操作问题,有人提出可以用setAttribute与removeAttribute的方法对类名进行操作,我觉得很不解:我以为只有classList.add()或classList.remove()这种方法可以解决这种需求,可是有人提出了用setAttribute('class', 'xxx')和removeAttribute('class')的方法。第一感觉就是局限性与不安全:第一只能将类名更改为指定结果,第二删除class属性的做法从来没有见过。请问对类名的操作中是否这样的做法是否具有可行性??

阅读 6.6k
4 个回答

其实如果只是想要处理增删class的话,也可以选择使用className来做,这样也可以避免classList的兼容性问题。

可以选择自行封装两个增删的方法出来。

实现代码如下

ele.className += ' clsName'; //添加类名
ele.className = ele.className.replace(/ ?deleteClsName/g,''); //删除类名

removeAttribute 是用来删除指定属性的, class 也是属性,自然可以删除。classList 是 HTML5 的 API,如果只能用它来添加删除,你让不支持 classList 的浏览器版本情何以堪。另外这种问题试一下不就知道了。

为什么不用addClass....

setAttribute修改的是class这一个整体属性,如果你要用来处理class,你还需要做判断

class="test1 test2 test3";这种情况下,你要setAttribute,你需要先判断你的value存在不,不存在增加,存在不做处理。remove的话,你要判断存在不存在,不存在,不处理,存在的话,不能把其他的删除。。。。

兼容性

setAttributeremoveAttribute 不存在兼容问题,classListie 低版本上存在兼容问题。

使用情景

setAttribute()removeAttribute()

正如方法名字所体现的,setAttribute()removeAttribute() 所处理的是元素的属性。当使用 setAttribute('class', 'foo')removeAttribute('class') ,处理的是元素的 class 整体 属性值,对 class 进行整个新增、替换和删除,例如 :

let a = document.querySelector('a')

// step1:设置 class 的 属性值为 foo
a.setAttribute('class', 'foo') // a.className === 'foo'

// step2:'foo foo' 作为整个参数传入,class 值就是该参数,所以有重复的类名
a.setAttribute('class', 'foo foo') // a.className === 'foo foo'

// step3:说明有一个属性节点 class
a.attributes // NamedNodeMap {0: class, length: 1}

// step4:移除 class 属性
a.removeAttribute('class') 

// step5:说明属性节点 class 被移除
a.attributes // NamedNodeMap { length: 0 } 

classList

可以直接通过设置 classList,这样就与 setAttribute('class') 功能相同,也是对整个 class 进行操作。

let a = document.querySelector('a')

a.classList = 'foo' // a.className === 'foo'

a.classList = 'foo foo' // a.className === 'foo foo'

a.classList = ''
a.attributes // NamedNodeMap {0: class, length: 1}

classList.add()classList.remove()

与上面对应是 classList 中的两个方法,classList.add()classList.remove() 是对 classList 数组内的元素进行增加和删除,例如

let a = document.querySelector('a')

// step1:设置 class 的 属性值为 foo
a.classList.add('foo') // a.className === 'foo'

// step1:一次传入两个相同参数,add() 方法会对传入参数进行检查,不会出现相同类名
a.classList.add('foo', 'foo') // a.className === 'foo'

// step3:说明有一个属性节点 class
a.attributes // NamedNodeMap {0: class, length: 1}

// step4:移除 class 属性
a.classList.remove('foo') 

// step5:说明 class 上的属性值已经被移除,但是属性节点 class 还在
a.classList [value: ""]
a.attributes // NamedNodeMap {0: class, length: 1}

总结

通过对比,我们可以看出 setAttribute('class', 'foo')removeAttribute('class')classList 的操作都是针对整个class属性的,而 classList 下的方法 add()remove() 则是针对 classList 数组进行操作的。所以,在使用时,如果是不管元素上面的 class 有什么,只需要将其设置成我们想要的属性时,我们可以使用 setAttribute('class', 'foo')classList 来设置。当然,也可以通过正则或者其他方法,达到替换某个类的效果(如 'foo boo' -> 'foo voo'),但是这样本质上是整个替换,而 classList.add()classList.remove() 则更加直接地对某个类进行增加、修改或删除,也避免了重复添加相同类的尴尬。
以上的都是通过 chrome 调试器测试而归纳出来的结论,相当于经过了一个黑盒,如有错误请提出。当然,区分它们的不同最直接就是查看他们的源码看看里面的具体实现。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题