JavaScript-DOM(四)

举报
Johan Tian 发表于 2022/07/13 13:47:34 2022/07/13
【摘要】 2、元素的标准属性HTML 元素的标准属性(即在标准中定义的属性),会自动成为元素节点对象的属性。// <a id="aId" href="http://www.example.com" class="aClass">链接</a>var a = document.getElementById('test');// a是节点对象,id和href自动成为a节点的属性a.id // "aId"a...

2、元素的标准属性

HTML 元素的标准属性(即在标准中定义的属性),会自动成为元素节点对象的属性

// <a id="aId" href="http://www.example.com" class="aClass">链接</a>
var a = document.getElementById('test');
// a是节点对象,id和href自动成为a节点的属性
a.id // "aId"
a.href // "http://www.example.com/"
a.className // "aClass"

上面代码中,a元素标签的属性idhref,自动成为节点对象的属性。

这些属性都是可写的。

var img = document.getElementById('myImage');
img.src = 'http://www.example.com/image.jpg';

上面的写法,会立刻替换掉img对象的src属性,即会显示另外一张图片。

这种修改属性的方法,常常用于添加表单的属性。

var f = document.forms[0];
f.action = 'submit.php';
f.method = 'POST';

上面代码为表单添加提交网址和提交方法。

注意,这种用法虽然可以读写属性,但是无法删除属性delete运算符在这里不会生效。

HTML 元素的属性名是大小写不敏感的,但是 JavaScript 对象的属性名是大小写敏感的。转换规则是,转为 JavaScript 属性名时,一律采用小写。如果属性名包括多个单词,则采用骆驼拼写法,即从第二个单词开始,每个单词的首字母采用大写,比如onClick

有些 HTML 属性名是 JavaScript 的保留字,转为 JavaScript 属性时,必须改名。主要是以下两个。

  • for属性改为htmlFor
  • class属性改为className

另外,HTML 属性值一般都是字符串,但是 JavaScript 属性会自动转换类型。比如,将字符串true转为布尔值,将onClick的值转为一个函数,将style属性的值转为一个CSSStyleDeclaration对象。因此,可以对这些属性赋予各种类型的值。

3、属性操作的标准方法

3.1 概述

元素节点提供六个方法,用来操作属性。

  • getAttribute()
  • getAttributeNames()
  • setAttribute()
  • hasAttribute()
  • hasAttributes()
  • removeAttribute()

这有几点注意。

(1)适用性

这六个方法对所有属性(包括用户自定义的属性)都适用

(2)返回值

getAttribute()只返回字符串,不会返回其他类型的值。

(3)属性名

这些方法只接受属性的标准名称,不用改写保留字,比如forclass都可以直接使用。另外,这些方法对于属性名是大小写不敏感的。

var image = document.images[0];
image.setAttribute('class', 'myImage');

上面代码中,setAttribute方法直接使用class作为属性名,不用写成className

3.2 Element.getAttribute() 返回元素的指定属性值,字符串

Element.getAttribute方法返回当前元素节点的指定属性。如果指定属性不存在,则返回null

// HTML 代码为
// <div id="div1" align="left">
var div = document.getElementById('div1');
div.getAttribute('align') // "left"

3.3 Element.getAttributeNames() 返回一个数组,成员是元素的所有属性的名字

Element.getAttributeNames()返回一个数组,成员是当前元素的所有属性的名字。如果当前元素没有任何属性,则返回一个空数组。使用Element.attributes属性,也可以拿到同样的结果,唯一的区别是它返回的是类似数组的对象。

var mydiv = document.getElementById('mydiv');
mydiv.getAttributeNames().forEach(function (key) {
  var value = mydiv.getAttribute(key);
  console.log(key, value);
})

上面代码用于遍历某个节点的所有属性。

3.4 Element.setAttribute() 为元素设置(新增)属性

Element.setAttribute方法用于为当前元素节点新增属性。如果同名属性已存在,则相当于编辑已存在的属性。该方法没有返回值。

// HTML 代码为
// <button>Hello World</button>
var b = document.querySelector('button');
b.setAttribute('name', 'myButton');
b.setAttribute('disabled', true); // 属性值总是字符串,其他类型会转成字符串,这里会转成字符串'true'

上面代码中,button元素的name属性被设成myButtondisabled属性被设成true

这里有两个地方需要注意,首先,属性值总是字符串,其他类型的值会自动转成字符串,比如布尔值true就会变成字符串true;其次,上例的disable属性是一个布尔属性,对于<button>元素来说,这个属性不需要属性值,只要设置了就总是会生效,因此setAttribute方法里面可以将disabled属性设成任意值。

3.5 Element.hasAttribute() 是否包含指定属性

Element.hasAttribute方法返回一个布尔值,表示当前元素节点是否包含指定属性

var d = document.getElementById('div1');
if (d.hasAttribute('align')) {
  d.setAttribute('align', 'center');
}

上面代码检查div节点是否含有align属性。如果有,则设置为居中对齐。

3.6 Element.hasAttributes() 是否有任何的属性

Element.hasAttributes方法返回一个布尔值,表示当前元素是否有属性,如果没有任何属性,就返回false,否则返回true

var foo = document.getElementById('foo');
foo.hasAttributes() // true

3.7 Element.removeAttribute() 移除指定属性

Element.removeAttribute方法移除指定属性。该方法没有返回值

// HTML 代码为
// <div id="div1" align="left" width="200px">
document.getElementById('div1').removeAttribute('align');
// 现在的HTML代码为
// <div id="div1" width="200px">

4、dataset 属性 获取data-*自定义属性

有时,需要在HTML元素上附加数据,供 JavaScript 脚本使用。一种解决方法是自定义属性

<div id="mydiv" foo="bar">

上面代码为div元素自定义了foo属性,然后可以用getAttribute()setAttribute()读写这个属性。

var n = document.getElementById('mydiv');
n.getAttribute('foo') // bar
n.setAttribute('foo', 'baz')

这种方法虽然可以达到目的,但是会使得 HTML 元素的属性不符合标准,导致网页代码通不过校验。

更好的解决方法是,使用标准提供的data-*属性

<div id="mydiv" data-foo="bar">

然后,使用元素节点对象的dataset属性,它指向一个对象,可以用来操作 HTML 元素标签的data-*属性。

var n = document.getElementById('mydiv');
n.dataset.foo // bar  省略data-,直接访问foo即可访问到 data-foo的值
n.dataset.foo = 'baz'

上面代码中,通过dataset.foo读写data-foo属性。

删除一个data-*属性,可以直接使用delete命令。

delete document.getElementById('myDiv').dataset.foo;

除了dataset属性,也可以用getAttribute('data-foo')removeAttribute('data-foo')setAttribute('data-foo')hasAttribute('data-foo')等方法操作data-*属性。

注意,data-后面的属性名有限制,只能包含字母、数字、连词线(-)、点(.)、冒号(:)和下划线(_)。而且,属性名不应该使用AZ的大写字母,比如不能有data-helloWorld这样的属性名,而要写成data-hello-world

data-后面不能使用驼峰写法,可以使用烤串写法。

转成dataset的键名时,连词线后面如果跟着一个小写字母,那么连词线会被移除,该小写字母转为大写字母,其他字符不变。反过来,dataset的键名转成属性名时,所有大写字母都会被转成连词线+该字母的小写形式,其他字符不变。比如,dataset.helloWorld会转成data-hello-world

通过dataset访问的时候,如有烤串写法属性需通过驼峰写法访问

八、Text 节点和 DocumentFragment 节点

1、Text 节点的概念

文本节点(Text)代表元素节点(Element)和属性节点(Attribute)的文本内容。如果一个节点只包含一段文本,那么它就有一个文本子节点,代表该节点的文本内容。

通常我们使用父节点的firstChildnextSibling等属性获取文本节点,或者使用Document节点的createTextNode方法创造一个文本节点。

// 获取文本节点
var textNode = document.querySelector('p').firstChild;
// 创造文本节点
var textNode = document.createTextNode('Hi');
document.querySelector('div').appendChild(textNode);

浏览器原生提供一个**Text构造函数**。它返回一个文本节点实例。它的参数就是该文本节点的文本内容。

// 空字符串
var text1 = new Text(); // 返回一个文本实例
// 非空字符串
var text2 = new Text('This is a text node'); // 参数为该文本节点的文本内容

注意,由于空格也是一个字符,所以哪怕只有一个空格,也会形成文本节点。比如,包含一个空格,它的子节点就是一个文本节点。

文本节点除了继承Node接口,还继承了CharacterData接口Node接口的属性和方法请参考《Node 接口》一章,这里不再重复介绍了,以下的属性和方法大部分来自CharacterData接口。

2、Text 节点的属性

2.1 data 设置或读取文本节点内容

data属性等同于nodeValue属性,用来设置或读取文本节点的内容

// 读取文本内容
document.querySelector('p').firstChild.data
// 等同于
document.querySelector('p').firstChild.nodeValue
// 设置文本内容
document.querySelector('p').firstChild.data = 'Hello World';

2.2 wholeText 当前文本和毗邻文本节,作为整体返回

wholeText属性将当前文本节点与毗邻的文本节点,作为一个整体返回。大多数情况下,wholeText属性的返回值,与data属性和textContent属性相同。但是,某些特殊情况会有差异。

举例来说,HTML 代码如下。

<p id="para">A <em>B</em> C</p>

这时,文本节点的wholeText属性和data属性,返回值相同。

var el = document.getElementById('para');
el.firstChild.wholeText // "A "
el.firstChild.data // "A "

但是,一旦移除<em>节点,wholeText属性与data属性就会有差异,因为这时其实<p>节点下面包含了两个毗邻的文本节点。

el.removeChild(para.childNodes[1]);
el.firstChild.wholeText // "A C"
el.firstChild.data // "A "

2.3 length 文本长度

length属性返回当前文本节点的文本长度

(new Text('Hello')).length // 5

2.4 nextElementSibling 后一个兄弟元素节点,previousElementSibling 前一个兄弟元素节点

nextElementSibling属性返回紧跟在当前文本节点后面的那个同级元素节点。如果取不到元素节点,则返回null

// HTML 为
// <div>Hello <em>World</em></div>
var tn = document.querySelector('div').firstChild;
tn.nextElementSibling
// <em>World</em>

previousElementSibling属性返回当前文本节点前面最近的同级元素节点。如果取不到元素节点,则返回null:

3、Text 节点的方法

3.1 appendData(),deleteData(),insertData(),replaceData(),substringData()

以下5个方法都是编辑Text节点文本内容的方法

  • appendData():在Text节点尾部追加字符串
  • deleteData()删除Text节点内部的子字符串,第一个参数为子字符串开始位置,第二个参数为子字符串长度。
  • insertData():在Text节点插入字符串,第一个参数为插入位置,第二个参数为插入的子字符串。
  • replaceData():用于替换文本,第一个参数为替换开始位置,第二个参数为需要被替换掉的长度,第三个参数为新加入的字符串。
  • substringData():用于获取子字符串,第一个参数为子字符串在Text节点中的开始位置,第二个参数为子字符串长度。
// HTML 代码为
// <p>Hello World</p>
var pElementText = document.querySelector('p').firstChild;
pElementText.appendData('!');
// 页面显示 Hello World!
pElementText.deleteData(7, 5);
// 页面显示 Hello W
pElementText.insertData(7, 'Hello ');
// 页面显示 Hello WHello
pElementText.replaceData(7, 5, 'World');
// 页面显示 Hello WWorld
pElementText.substringData(7, 10);
// 页面显示不变,返回"World "

3.2 remove() 移除Text节点

remove方法用于移除当前Text节点。

// HTML 代码为
// <p>Hello World</p>
document.querySelector('p').firstChild.remove()
// 现在 HTML 代码为
// <p></p>

3.3 splitText() 分割Text节点变为两个

splitText方法Text节点一分为二,变成两个毗邻的Text节点。它的参数就是分割位置(从零开始),分割到该位置的字符前结束。如果分割位置不存在,将报错。

分割后,该方法返回分割位置后方的字符串,而原Text节点变成只包含分割位置前方的字符串。

// html 代码为 <p id="p">foobar</p>
var p = document.getElementById('p');
var textnode = p.firstChild;
var newText = textnode.splitText(3);
newText // "bar"
textnode // "foo"

父元素节点的normalize方法可以将毗邻的两个Text节点合并。

接上面的例子,文本节点的splitText方法将一个Text节点分割成两个,父元素的normalize方法可以实现逆操作,将它们合并。

p.childNodes.length // 2
// 将毗邻的两个 Text 节点合并
p.normalize();
p.childNodes.length // 1

4、DocumentFragment 文档片段节点

DocumentFragment节点代表一个文档的片段,本身就是一个完整的 DOM 树形结构。它没有父节点parentNode返回null,但是可以插入任意数量的子节点。它不属于当前文档,操作DocumentFragment节点,要比直接操作 DOM 树快得多。

它一般用于构建一个 DOM 结构,然后插入当前文档。document.createDocumentFragment方法,以及浏览器原生的DocumentFragment构造函数,可以创建一个空的DocumentFragment节点。然后再使用其他 DOM 方法,向其添加子节点。

var docFrag = document.createDocumentFragment();
// 等同于
var docFrag = new DocumentFragment();
var li = document.createElement('li');
li.textContent = 'Hello World';
docFrag.appendChild(li);
document.querySelector('ul').appendChild(docFrag);

上面代码创建了一个DocumentFragment节点,然后将一个li节点添加在它里面,最后将DocumentFragment节点移动到原文档。

注意DocumentFragment节点本身不能被插入当前文档。当它作为appendChild()insertBefore()replaceChild()等方法的参数时,是它的所有子节点插入当前文档,而不是它自身。一旦DocumentFragment节点被添加进当前文档,它自身就变成了空节点(textContent属性为空字符串),可以被再次使用。如果想要保存DocumentFragment节点的内容,可以使用cloneNode方法。

document
  .querySelector('ul')
  .appendChild(docFrag.cloneNode(true));

上面这样添加DocumentFragment节点进入当前文档,不会清空DocumentFragment节点。

下面是一个例子,使用DocumentFragment反转一个指定节点的所有子节点的顺序。

function reverse(n) {
  var f = document.createDocumentFragment();
  while(n.lastChild) f.appendChild(n.lastChild);
  n.appendChild(f);
}

DocumentFragment节点对象没有自己的属性和方法,全部继承自Node节点和ParentNode接口。也就是说,DocumentFragment节点比Node节点多出以下四个属性。

  • children:返回一个动态的HTMLCollection集合对象,包括当前DocumentFragment对象的所有子元素节点。
  • firstElementChild:返回当前DocumentFragment对象的第一个子元素节点,如果没有则返回null
  • lastElementChild:返回当前DocumentFragment对象的最后一个子元素节点,如果没有则返回null
  • childElementCount:返回当前DocumentFragment对象的所有子元素数量。

八、CSS 操作

CSS 与 JavaScript 是两个有着明确分工的领域,前者负责页面的视觉效果,后者负责与用户的行为互动。但是,它们毕竟同属网页开发的前端,因此不可避免有着交叉和互相配合。本章介绍如何通过 JavaScript 操作 CSS

1、HTML 元素的 style 属性

操作 CSS 样式最简单的方法,就是使用网页元素节点的getAttribute()方法、setAttribute()方法和removeAttribute()方法,直接读写或删除网页元素的style属性。

div.setAttribute(
  'style',
  'background-color:red;' + 'border:1px solid black;'
);

上面的代码相当于下面的 HTML 代码。

<div style="background-color:red; border:1px solid black;" />

style不仅可以使用字符串读写,它本身还是一个对象,部署了 CSSStyleDeclaration 接口(详见下面的介绍),可以直接读写个别属性

e.style.fontSize = '18px';
e.style.color = 'black';

2、CSSStyleDeclaration 接口

2.1 简介 - 用来操作元素的样式,可读写

CSSStyleDeclaration 接口用来操作元素的样式。三个地方部署了这个接口。

  • 元素节点的style属性(Element.style
  • CSSStyle实例的style属性
  • window.getComputedStyle()的返回值

CSSStyleDeclaration 接口可以直接读写 CSS 的样式属性,不过,连词号需要变成骆驼拼写法。

var divStyle = document.querySelector('div').style;
// 可读写
divStyle.backgroundColor = 'red';
divStyle.border = '1px solid black';
divStyle.width = '100px';
divStyle.height = '100px';
divStyle.fontSize = '10em';
// 注意,读的样式只是行内样式,不能读取样式表的样式
divStyle.backgroundColor // red
divStyle.border // 1px solid black
divStyle.height // 100px
divStyle.width // 100px

上面代码中,style属性的值是一个 CSSStyleDeclaration 实例。这个对象所包含的属性与 CSS 规则一一对应,但是名字需要改写,比如background-color写成backgroundColor。改写的规则是将横杠从 CSS 属性名中去除,然后将横杠后的第一个字母大写。如果 CSS 属性名是 JavaScript 保留字,则规则名之前需要加上字符串css,比如**float写成cssFloat**。

改写规则:烤串变驼峰,保留字前加css

注意,该对象的属性值都是字符串,设置时必须包括单位,但是不含规则结尾的分号。比如,divStyle.width不能写为100,而要写为100px

另外,Element.style返回的只是行内样式,并不是该元素的全部样式。通过样式表设置的样式,或者从父元素继承的样式,无法通过这个属性得到。元素的全部样式要通过window.getComputedStyle()得到。

2.2 CSSStyleDeclaration 实例属性

(1)CSSStyleDeclaration.cssText 用来读写所有行内样式

CSSStyleDeclaration.cssText属性用来读写当前规则的所有样式声明文本

var divStyle = document.querySelector('div').style;
divStyle.cssText = 'background-color: red;' // 会覆盖原有的整个行内样式
  + 'border: 1px solid black;'
  + 'height: 100px;'
  + 'width: 100px;';

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

删除一个元素的所有行内样式,最简便的方法就是设置cssText为空字符串。

divStyle.cssText = '';
(2)CSSStyleDeclaration.length 行内样式的长度

CSSStyleDeclaration.length属性返回一个整数值,表示当前规则包含多少条样式声明。

// HTML 代码如下
// <div id="myDiv"
//   style="height: 1px;width: 100%;background-color: #CA1;"
// ></div>
var myDiv = document.getElementById('myDiv');
var divStyle = myDiv.style;
divStyle.length // 3

上面代码中,myDiv元素的行内样式共包含3条样式规则。

(3)CSSStyleDeclaration.parentRule 返回当前规则所属的那个样式块

CSSStyleDeclaration.parentRule属性返回当前规则所属的那个样式块(CSSRule 实例)。如果不存在所属的样式块,该属性返回null

该属性只读,且只在使用 CSSRule 接口时有意义。

var declaration = document.styleSheets[0].rules[0].style;
declaration.parentRule === document.styleSheets[0].rules[0]
// true

2.3 CSSStyleDeclaration 实例方法

(1)CSSStyleDeclaration.getPropertyPriority() 指定样式有没有设置important优先级

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

// HTML 代码为
// <div id="myDiv" style="margin: 10px!important; color: red;"/>
var style = document.getElementById('myDiv').style;
style.margin // "10px"
style.getPropertyPriority('margin') // "important"
style.getPropertyPriority('color') // ""

上面代码中,margin属性有important优先级,color属性没有。

(2)CSSStyleDeclaration.getPropertyValue() 返回指定样式的值

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

// HTML 代码为
// <div id="myDiv" style="margin: 10px!important; color: red;"/>
var style = document.getElementById('myDiv').style;
style.margin // "10px"
style.getPropertyValue("margin") // "10px"
(3)CSSStyleDeclaration.item() 返回指定位置的CSS属性名

CSSStyleDeclaration.item方法接受一个整数值作为参数,返回该位置的 CSS 属性名

// HTML 代码为
// <div id="myDiv" style="color: red; background-color: white;"/>
var style = document.getElementById('myDiv').style;
style.item(0) // "color"
style.item(1) // "background-color"

上面代码中,0号位置的 CSS 属性名是color1号位置的 CSS 属性名是background-color

如果没有提供参数,这个方法会报错。如果参数值超过实际的属性数目,这个方法返回一个空字符值。

(4)CSSStyleDeclaration.removeProperty() 移除指定CSS属性,并返回原来的值

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

// HTML 代码为
// <div id="myDiv" style="color: red; background-color: white;">
//   111
// </div>
var style = document.getElementById('myDiv').style;
style.removeProperty('color') // 'red'
// HTML 代码变为
// <div id="myDiv" style="background-color: white;">

上面代码中,删除color属性以后,字体颜色从红色变成默认颜色。

(5)CSSStyleDeclaration.setProperty() 设置新的 CSS 属性

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

该方法可以接受三个参数。

  • 第一个参数:属性名,该参数是必需的。
  • 第二个参数:属性值,该参数可选。如果省略,则参数值默认为空字符串。
  • 第三个参数:优先级,该参数可选。如果设置,唯一的合法值是important,表示 CSS 规则里面的!important
// HTML 代码为
// <div id="myDiv" style="color: red; background-color: white;">
//   111
// </div>
var style = document.getElementById('myDiv').style;
style.setProperty('border', '1px solid blue');

上面代码执行后,myDiv元素就会出现蓝色的边框。

3、CSS 模块的侦测(判断浏览器是否支持某个样式)

CSS 的规格发展太快,新的模块层出不穷。不同浏览器的不同版本,对 CSS 模块的支持情况都不一样。有时候,需要知道当前浏览器是否支持某个模块,这就叫做“CSS模块的侦测”。

判断浏览器是否支持某个样式

一个比较普遍适用的方法是,判断元素的style对象的某个属性值是否为字符串。

typeof element.style.animationName === 'string';
typeof element.style.transform === 'string';

如果该 CSS 属性确实存在,会返回一个字符串。即使该属性实际上并未设置,也会返回一个空字符串。如果该属性不存在,则会返回undefined

document.body.style['maxWidth'] // ""
document.body.style['maximumWidth'] // undefined

上面代码说明,这个浏览器支持max-width属性,但是不支持maximum-width属性。

注意,不管 CSS 属性名的写法带不带连词线,style属性上都能反映出该属性是否存在。

document.body.style['backgroundColor'] // ""
document.body.style['background-color'] // ""

另外,使用的时候,需要把不同浏览器的 CSS 前缀也考虑进去。

var content = document.getElementById('content');
typeof content.style['webkitAnimation'] === 'string'

这种侦测方法可以写成一个函数。

function isPropertySupported(property) {
  if (property in document.body.style) return true;
  var prefixes = ['Moz', 'Webkit', 'O', 'ms', 'Khtml'];
  var prefProperty = property.charAt(0).toUpperCase() + property.substr(1);
  for(var i = 0; i < prefixes.length; i++){
    if((prefixes[i] + prefProperty) in document.body.style) return true;
  }
  return false;
}
isPropertySupported('background-clip')
// true

4、原生CSS 对象

浏览器原生提供 CSS 对象,为 JavaScript 操作 CSS 提供一些工具方法。

这个对象目前有两个静态方法。

4.1 CSS.escape() 转义CSS选择器里的特殊字符

CSS.escape方法用于转义 CSS 选择器里面的特殊字符。

<div id="foo#bar">

上面代码中,该元素的id属性包含一个#号,该字符在 CSS 选择器里面有特殊含义。不能直接写成document.querySelector('#foo#bar'),只能写成document.querySelector('#foo\\#bar')。这里必须使用双斜杠的原因是,单引号字符串本身会转义一次斜杠。

CSS.escape方法就用来转义那些特殊字符。

document.querySelector('#' + CSS.escape('foo#bar'))
//CSS.escape('foo#bar')转义成foo\#bar

4.2 CSS.supports() 当前环境是否支持某一句 CSS 规则

CSS.supports方法返回一个布尔值,表示当前环境是否支持某一句 CSS 规则

它的参数有两种写法,一种是第一个参数是属性名,第二个参数是属性值;另一种是整个参数就是一行完整的 CSS 语句。

// 第一种写法
CSS.supports('transform-origin', '5px') // true
// 第二种写法
CSS.supports('display: table-cell') // true

注意,第二种写法的参数结尾不能带有分号,否则结果不准确。

CSS.supports('display: table-cell;') // false

5、window.getComputedStyle() 返回元素最终样式

行内样式(inline style)具有最高的优先级,改变行内样式,通常会立即反映出来。但是,网页元素最终的样式是综合各种规则计算出来的。因此,如果想得到元素实际的样式,只读取行内样式是不够的,需要得到浏览器最终计算出来的样式规则。

window.getComputedStyle方法,就用来返回浏览器计算后得到的最终样式规则。它接受一个元素节点对象作为参数,返回一个 CSSStyleDeclaration 实例,包含了指定节点的最终样式信息。所谓“最终样式信息”,指的是各种 CSS 规则叠加后的结果。

var div = document.querySelector('div');
var styleObj = window.getComputedStyle(div);
styleObj.backgroundColor

上面代码中,得到的背景色就是div元素真正的背景色。

注意,CSSStyleDeclaration 实例是一个活的对象,任何对于样式的修改,会实时反映到这个实例上面。另外,这个实例是只读的

getComputedStyle方法还可以接受第二个参数,表示当前元素的伪元素(比如:before:after:first-line:first-letter等)。

var result = window.getComputedStyle(div, ':before');

下面的例子是如何获取元素的高度。

var elem = document.getElementById('elem-container');
var styleObj = window.getComputedStyle(elem, null)
var height = styleObj.height; // 得到元素最终渲染出来的高度,最可靠
// 等同于
var height = styleObj['height'];
var height = styleObj.getPropertyValue('height');

上面代码得到的height属性,是浏览器最终渲染出来的高度,比其他方法得到的高度更可靠。由于styleObj是 CSSStyleDeclaration 实例,所以可以使用各种 CSSStyleDeclaration 的实例属性和方法。

有几点需要注意。

  • CSSStyleDeclaration 实例返回的 CSS 值都是绝对单位。比如,长度都是像素单位(返回值包括px后缀),颜色是rgb(#, #, #)rgba(#, #, #, #)格式
  • CSS 规则的简写形式无效。比如,想读取margin属性的值,不能直接读,只能读marginLeftmarginTop等属性;再比如,font属性也是不能直接读的,只能读font-size等单个属性。
  • 如果读取 CSS 原始的属性名,要用方括号运算符,比如styleObj['z-index'];如果读取骆驼拼写法的 CSS 属性名,可以直接读取styleObj.zIndex
  • 该方法返回的 CSSStyleDeclaration 实例的cssText属性无效,返回undefined
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。