DOM系列:样式和类

对于任何一位Web开发者而言,处理CSS样式很多时候还是会借助JavaScript。简单的说,我们会碰到一些交互(或UI效果的变化)都会通过JavaScript来处理或类。那么今天我们将要学习的是如何通过JavaScript来控制样式和类名,在深入讨论JavaScript处理样式和类的方法之前,我们需要知道在Web页面中元素的样式处理通常有两种方式。

在HTML添加类名,然后在CSS样式文件中处理样式

通过JavaScript控制HTML元素的属性,改变元素样式

虽然上面提到的方法都可以处理页面元素的样式,但CSS始终是最佳选择 —— 不仅对HTML如此,在JavaScript中也是如此。因为我们一直遵守的是:分离

当然很多时候,只使用CSS的类方式并不一定能达到我们要的结果(也就是说类再也无法处理时),那么我们就必须使用JavaScript操作HTML元素中的属性。 比如,如果我们要动态计算元素的坐标,并想通过JavaScript来设置,那么我们就可以像下面这样做:

这只是其中的一种情景,事实上还有很多其他的情景,比如将文本的颜色变成红色,比如添加一个背景图片。其实,通过JavaScript来控制CSS类名,更灵活,更容易支持。

至于为什么要这么做,或者要怎么做,接下来的内容就是围绕着这些方面来阐述,感兴趣的,欢迎继续往下阅读。

为什么要使用JavaScript设置样式

文章开头我们提到了可以通过JavaScript来控制Web的样式。那么为什么要使用JavaScript设置元素样式?在深入讨论之前,我们有必要知识为什么要使用JavaScript来设置元素样式。在常见的情况下,咱们可以通过样式文件(就是文件或标签)或内联样式(元素中调用属性)来控制Web元素的外观。这也可能是大家更多时候想要的。

但在很多时候,是希望内容更具交互性,打个比方说,你希望根据用户输入的状态(比如鼠标单击或者悬浮)引入别的样式,这些样式代码在后台运行。虽然像这样的伪选择器提供了一些支持,但是功能还是有很多限制。

言外之意,很多更具交互性(或者说更多的富交互性)的解决方案是需要强度依赖JavaScript。JavaScript不仅可以让你在与之交互的元素上进行样式变化,更重要的是,它允许你在整个页面中使用样式。可以说这种自由性是非常强大的,而且远远超出了CSS对内容样式能力的限制。

两种处理样式的方式

正如文章开头提到的,如果要控制元素的样式变化,有两种方法可能使用JavaScript来修改。一种方法是直接在元素上设置CSS属性(其实就是通过元素内联的属性来实现)。另一种方法是从元素中添加或删除类名,这可能导致Web运用或Web程序忽略某些样式规则。接下来我们会围绕着这两种方式进行深入的学习。

直接设置

在学习如何直接修改元素的(或者如标题写的一样,直接通过设置)属性来改变元素的样式之前,需要先花点时间来了解接口。

接口可以用来操作元素的样式。常见的方式(接口)有:

元素节点的属性,即,也就是前面介绍的方式

实例的属性,即

通过JavaScript访问的每个HTML元素都有一个对象。该对象允许您指定CSS属性并设置其值。比如你在浏览器控制台中输入就可以看到类似下图这样的一个截图:

从上图可以看出来,对象下有的CSS属性。言外之意,上图中的CSS属性(还有很多没截到,可以点击这里查阅读所有的属性)可以通过的方式来设置对应属性的值。例如,咱们想对设置背景颜色:

$0.style.backgroundColor ='#d93600'

事实上对应的就是你在浏览器控制台中选中的元素。

简单地说,要直接使用JavaScript来控制元素样式,第一步是要选中要被修改样式的元素。上面示例使用的是这样的快速选择元素方式(在浏览器控制台中可以这么使用),在JavaScript中,可以使用方法选中元素,当然在JavaScript中还可以使用其他的方式,比如前面《 和 》一文中介绍选中元素的方法。第二步是找到你关心的CSS属性(想要更换的CSS样式属性,比如上例中的,其实对应的就是CSS中的),然后给该属性赋值。需要注意的是,CSS中的许多值实际上是字符串。也要记住,很多值需要带有像或这样的度量单位才能被识别。

通过方式修改元素的样式,实际上修改的是HTML元素的属性的值。比如:

总而言之,可以控制HTML元素的属性来修改任何你想修改的HTML元素的样式

也就是说,是HTML元素的一个标签属性,也就是说它也是元素节点。既然是DOM元素的节点,我们就可以通过、和等方法来读写或删除DOM元素的属性。就上面的示例,咱们可以使用实现同样的效果,比如:

$0.setAttribute(

'style',

'background-color: orange; z-index: 9999; border-left-width: 5px;'

)

如果你对、和从未接触或不太了解,建议你花点时间阅读前面整理的文章《和》一文。

上面的示例演示了属性来给HTML元素添加样式,其效果等同于使用。事实上,属性返回的是一个对象,表示元素的内联属性,但会忽略样式表应用的属性。

接口中的接口除了给HTML元素写CSS样式之外,也可以读:

$0.style.backgroundColor // =>"orange"

$0.style.zIndex // =>"9999"

$0.style.borderLeftWidth // =>"5px"

上面代码中,属性的值是一个实例。这个对象所包含的属性与CSS规则一一对应,但CSS属性名需要改写,比如要改成驼峰写法,即。还有一点要特别的注意,如果CSS属性名是JavaScript保留字,则样式名之前需要加上字符串,比如要写成

前面的示例也看到了,除了通过方式给HTML元素的设置样式之外,还可以通过的方式来给属性添加样式。但对于要给一个元素添加多个属性值时,需要多次写,对于追求极速开发体验的码农而言,总感觉会有点蛋疼。在的属性用来读写当前元素的值。

先来看读:

$0.style.cssText

输入的值是:

background-color:orange;

z-index: 9999;

border-left-width: 5px;

同样的,如果我们要给一个元素添加样式,也可以使用方式,比如:

$0.style.cssText ='color:#f36; font-size: 2rem;padding: 10px'

这个时候对应的元素的值变成:

使用给元素的添加值是要特别注意,如果元素的属性一开始就有值,使用上面的方式添加值的话将会覆盖原有的属性值。比如:

值得庆幸的是,我们可以使用下面的方式来改变:

$0.style.cssText +='color:#f36; font-size: 2rem; padding: 10px'

其中、和属性被追加到元素的上,而不是直接覆盖,比如下图所示:

注意,使用的属性值不用改写CSS属性名。

另外,在使用时要给一个元素删除中的样式,可以给该方法设置值为空字符串,比如:

$0.style.cssText ='';

众所周知,HTML元素的行内样式是具有最高的优先级,改变行内样式,通常会立即反映出来。但是,HTML中DOM元素最终的样式是综合各种规则计算出来的。也就是说,要想得到元素实际样式,只读取行内样式是不够的,需要得到浏览器最终计算出来的样式规则。

至于CSS样式是怎么被浏览器计算出来的,真正要理解就要去理解浏览器的工作原理相关的知识了。有关于这部分就不在这里阐述了,如果你感兴趣,可以阅读下面几篇文章:

浏览器的渲染原理简介

浏览器的渲染:过程与原理

浏览器内核、JS 引擎、页面呈现原理及其优化

探究 CSS 解析原理

浏览器的工作原理:新式网络浏览器幕后揭秘

浏览器原理

如果你花时间阅读了上面的文章或者说你对浏览器渲染CSS有一定的了解的话,那么就知道,浏览器解析CSS样式一共有五个来源,其中开发人员只能接触其中的三个来源,HTML元素内联 属性,HTML的标签样式和引用样式;其中另外两个是浏览器客户端的样式:浏览器默认样式和浏览器用户自定义样式。用一张图简单的描述就如下图所示:

其实,如果你平时细心的话,在使用浏览器自带的开发者工具的时候,你就可以查看到浏览器对元素计算出来的属性,比如下图:

而在JavaScript中,咱们就可以使用方法返回浏览器计算后得到的最终样式规则(即计算出来的样式)。这个方法接受一个节点对象作为参数,返回一个实例,它包含了指定节点的最终样式信息。比如:

上图可以看到元素计算出来的最终样式信息。如果我们把其赋值给一个变量,比如,那么我们可以通过类似下面的方式取出元素对应的样式属性的值:

objStyle.color// => rgb(64, 64, 64)

objStyle.backgroundColor// => rgba(0, 0, 0, 0)

方法还可以接受第二个参数,表示当前元素的伪元素,比如、、和等。

window.getComputedStyle($0,':before')

需要注意的是,节点元素的对象无法读写伪元素的样式,这个时候就需要用到。使用JavaScript获取伪元素可以用类似下面这样的方法:

window.getComputedStyle($0,':before').color

除此之外,还可以使用接下来要介绍的实例的方法。比如:

window.getComputedStyle($0,':before').getPropertyValue('color')

在使用实例有几点需要注意:

实例返回的CSS值都是绝对单位。比如,长度都是像素单位,颜色是或格式

CSS规则的简写形式无效。比如,的值不能直接读,需要分开来读,比如、等

如果读取CSS原始的属性名,要用方括号运算符,比如,也可以换成驼峰方式

该方法返回的实例的属性无效,返回

实例的其他方法

实例除了上述的一些方法之外,还有其他的一些方法或属性。接下来咱们要学习的就是有关于他的属性和方法。

前面也提到过了,实例返回的是一个,那么我们的一些属性和方法也可以用到这里。比如、之类的等。比如:

letele = document.querySelector('#viewport')

letobjStyle = window.getComputedStyle(ele)objStyle.length// => 292

objStyle[]// => animation-delay

我们也可以通过循环把其每个属性打印出来,比如:

for(let i =; i

除此之外,还有几个实例方法:

方法接受 CSS 样式的属性名作为参数,返回一个字符串,表示有没有设置优先级。如果有就返回,否则返回空字符串。

方法接受 CSS 样式属性名作为参数,返回一个字符串,表示该属性的属性值。

方法接受一个属性名作为参数,在 CSS 规则里面移除这个属性,返回这个属性原来的值。

方法用来设置新的 CSS 属性。该方法没有返回值。

有关于更详细的介绍可以阅读:

原生JS 等方法解析

获取元素CSS值之方法熟悉

通过和控制样式

在我们Web的开发中,通过控制HTML元素的的类名(添加或删除),从而来控制元素的样式,这也是非常常见的方式。在JavaScript中,可以通过和来给元素添加或删除样式,从而实现元素样式的修改。

通过添加和删除类

通过前面的学习,我们知道属性允许你访问HTML元素的属性。通过可以读出HTML元素的属性的值。同样的,给赋值,可以给元素添加类名,但不同的是,新的类名将会覆盖旧的类名。比如下面这样的一个操作:

可以看到,新添加的类名,覆盖了已有的类名。如果想让新添加的类名不覆盖已有的类名,可以通过的方式来添加,比如:

$0.className +=' jhp'

这个时候重新打印,其值就是,在对应的HTML元素相比较而言就成功的添加了新的类名。

不过这样写,有点蛋疼,咱们可以将其封装成一个函数,比如:

有了这个函数之后,咱们就可以这样使用了:

addClass('.classdiv','highlight');addClass(document.getElementById('iddiv'),'highlight');

使用给指定的元素删除一个类名,相对来说比较麻烦一点。比如上例,咱们使用函数之后,通过可以读取出当前元素的的值为。如果我们要把类名重新恢复到时,只能像下面这样:

$0.className ='new jhp'

为了能更好的操作,咱们也可以类似于函数一样,写一个:

如果要在指定的元素中删除一个类名,就可以像下面这样使用:

removeClass($0,'new')

最后的结果正如我们所希望的一样:

特别声明,上面和两函数的的代码来源于@Yaphi Berhanu写的博文。

通过来添加和删除类等

上面看的是给指定元素的中添加和删除类。事实上,咱们还可以使用。在中主要的API有:

: 添加类名

:删除类名

:切换类名,如果改类名存在将会删除该类名,如果不存在将会添加该类名

:判断是否含有该类名,如果包含则返回,反之返回的是

比如我们当前元素,可以在浏览器中输出对应的值。从返回的结果上可以看出来,其返回的是。而且从其中可以找到对应的API,比如、、等。

这种类型表示一组空间分隔的标记。通常由, , 或返回。从开始的类JavaScript数组索引。始终是区分大小写的。

使用添加类名,咱们可以像下面这样:

$0.classList.add('make','me','look','rad')

通过可以判断元素是否包含指定的类名,如果包含返回的是,如果没包含返回的是:

$0.classList.contains('new') // =>false

$0.classList.contains('make') // =>true

使用可以删除指定的类名。比如:

其实该API就类似一个开关。打个比方说,如果当前元素中有指定的类名,那么执行该 API之后会将指定的类名删除,返之将会添加。类似这样的一个操作:

if($0.classList.contains('rad')) {

$0.classList.remove('rad');}else{

$0.classList.add('rad');}

上面的这个功能,就可以使用来替代:

$0.classList.toggle('cool')

使用表示:如果添加类,将返回,如果删除类,将返回:

let a =$0.classList.toggle('cool');console.log(a);//=>true

可以选择接受第二个参数,该参数是一个布尔值。可以根据第二个参数来控制是否添加还是删除类。

有了之后,那么前面写的和就可以修改一下了。把以前的替换成现在的。如此一来,代码会变得简单的多。比如:

其他API

除了上面一些常用的API之外,还有、属性以及、、和等。大家可以根据实际需要的去选择所需要的API。比如:

有关于更多的介绍可以阅读:

Adding, Removing & Toggling Classes With classList in JavaScript

Quick Tip: Add or Remove a CSS Class with Vanilla JavaScript

HTML5 DOM元素类名相关操作API classList简介

CSS操作

总结

通过上面的学习,知道如何通过JavaScript来修改CSS样式。我们平常中会使用到的方法会有:

通过DOM Element对象的、和等方法修改元素的属性

通过对元素节点的来读写行内CSS样式

通过对象的属性来修改全部的属性

通过对象的、、等方法来读写行内CSS样式

通过方法获得浏览器最终计算的样式规则

通过或给元素添加或删除类名,配合样式文件来修改元素样式

其实除了上述介绍的方法之外,咱们还可以直接添加样式。常见的方式是通过创建标签来添加内置的CSS样式表或者通过标签来引用外部样式表。另外还可以使用和来添加样式规则。不过在这篇文章我们没有介绍这些内容,我们将在后续的内容中再来学习这方面的知识。如果你对这方面的知识感兴趣,欢迎持续观注后续的更新。

由于自身是JavaScript的初学者,如果文章中有不对之处,烦请各位拍正。如果您在这方面有更多经验,欢迎在下面的评论中与我们一起分享。如果你觉得这篇文章帮助你了,欢迎给我打赏(^_^)!!!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180608B02O1X00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券