className VS classList

​关于className 和 classList ,原生的DOM API,当我们需要使用为了一个元素添加一个css类或者去除一个css类,就会用上它们,当然使用jq的,当我没说过….,虽然jq很强大,但是个人觉得开始学习的时候,直接上手jq是对以后的学习是很不友好的,除非你真的看过jq的源码。

​当然并不是说jq不好,个人觉得,相反在业务处理上还是一款神器。只是对于个人学习不友好,你不知道底层的DOM是什么样的,就去上手jq框架,但是框架迭代太快,很快会老去,但是基层知识永远会是潮流。

​所以,在学习的时候,我更偏向于学习原生操作,毕竟前端娱乐圈发展太快,众口纷说,但是所有高层建筑都是基于底层结构。

两者的概念

classList是什么?

​ 它隶属于HTML5中新增的DOM API之一。 ​ 它是元素的一个只读属性,返回一个元素的类属性的实时 DOMTokenList集合。 ​ 但是可以使用add(),remove() 方法来添加类和删除类。 ​ 此外还有其他内置的方法:

  • item ( Number ) 根据Number索引返回类名。

  • toggle ( String ) 添加或者删除类,第一个参数决定当前类名是否存在,存在则删除,否则则添加;第二参数决定第一个参数时候添加或者删除,第二个参数若为真则添加,否则则删除。

  • contains( String ) 判断是否有String这个类名。

    className是什么?

它是用来获取当前元素和修改当前元素的类列表。
使用方法很简单,直接使用:Element.className='<类名>'

它们的作用是什么?

​ 它们都是用来对当前元素的类进行修改,包括添加和删除。 ​ classList是对于DOM 2的一个扩展,让修改类名更加方便;相对于className,当元素的类名越来越多的时候,使用className是不大方便的,因此classlist作为方便的使用方案。 ​ ​ 由于classList和className是类似的功能,当当前浏览器不支持的classList时,可以自行使用className配合正则表达式来封装成classList里面的方法。可以对比一下className和classList中的参数使用方法,className相对于classList在设置类名的是 使用类与类之间用空格间隔的 ,即 "<类1> 空格 <类2>" ,而classList的参数设置添加类名则是: "<类1>","<类2>"

两者的兼容性

​ classList的兼容大部分的浏览器,但是对于IE9以下(包括IE9)是不支持的。
​ ​
作为DOM2 层级的className 是可以兼容所有低版本的浏览器,包括ie6以上,火狐2以上,Chrome 1以上等等。

相对于上述的两个图,结论是在兼容IE浏览器,尤其是6,7,8,9版本的时候,需要使用className去添加类名,至于IE10、IE11也是部分支持。

拓展:关于减少reflow(重排|回流)和repaint(重绘)

​ 回到话题 为什么要使用添加类名来改变当前元素的样式 ,因为这里是和回流与重绘有关系,即和内存消耗相关。 ​ 我们都知道浏览器在呈现一个页面的时候,会经过至少一次渲染,步骤如下:

  1. 构建DOM树;

  2. 构建CSS树;

  3. DOM树和CSS树两者合成渲染树;

  4. 布局(Layout)

  5. 绘制(Paint)

  6. 多层图层合并,呈现给用户。

​ 由此可以知道,每当重新渲染的时候,也就是当DOM树和CSS树发生改变时,就会触发reflow和repaint,因此在操作DOM的时候,往往会引起reflow或者repaint。引起reflow和repaint主要是DOM发生改变,当然还有其它会·引起,例如改变浏览器窗口等等。

如何肉眼观察到相应的改变? 可以去使用开发者工具的 layer

当我们想要去改变当前dom节点的时候,例如动态去改变当前元素的颜色、布局的时候,一般来说,常用的两种方式:

  1. 给元素一条条去添加样式,像ele.style.css属性 会形成一条条DOM改变。

  2. 为当前节点去一次性添加相对应的类名。

第一种方法里面也会有很多对DOM节点的读写,这种同步阻塞占用线程,会增加了浏览器内存消耗,影响了浏览器性能。其实浏览器本身已经设计了一个处理相关问题的机制,第二种方法就是一种很好的体现,可以一次性加载完对DOM元素的修改,也就是先把这些操作先缓存起来,等到需要的时候直接加载进来,相对于第一种方法,对性能优化了很多。

而这里也有一个关于 为什么尽量不要使用table布局的原因,而提倡使用div+css ,不难发现其实学校里官网、教务系统使用的最多的table布局,学校教学里也有这个弊端,也有建议身边的同学不要使用table布局。 因为,如果使用table布局的话,一个td的改变,会影响整个table元素,可想而知会造成整个table及其子元素发生变化,引起多轮重排和重绘。 这里稍微对repaintreflow 做了一个小讲解,这部分是和前端性能相关的。