JavaScript DOM
本文最后更新于:8 个月前
长文预警,本文内容包括:DOM概述、Node接口、Element接口、以及常见的document节点、Element节点、Text节点,和节点属性、css的操作
JavaScript DOM
参考声明:部分内容整理自DOM - 《阮一峰 JavaScript 教程》 - 书栈网 · BookStack,需要了解更多细节,请阅读原文
一、DOM 概述
1、DOM
DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)。
浏览器会根据 DOM 模型,将结构化文档(比如 HTML 和 XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree)。所有的节点和最终的树状结构,都有规范的对外接口。
DOM 只是一个接口规范,可以用各种语言实现。
2、节点
DOM 的最小组成单位叫做节点(node)
节点的类型有七种。
Document
:整个文档树的顶层节点DocumentType
:doctype
标签(比如<!DOCTYPE html>
)Element
:元素节点,网页的各种HTML标签(比如<body>
、<a>
等)Attr
:网页元素的属性(比如class="right"
)Text
:文本节点,标签之间或标签包含的文本Comment
:注释节点DocumentFragment
:文档的片段,一个存在于内容的DOM片段,常用来生成复杂DOM结构,然后再插入当前文档
浏览器提供一个原生的节点对象 Node,上面这七种节点都继承了 Node,因此具有一些共同的属性和方法。
3、节点树
浏览器原生提供document
节点,代表整个文档。
文档的第一层有两个节点,第一个是文档类型节点(<!doctype html>
)通过document.doctype
获取,第二个是 HTML 网页的顶层容器标签<html>
通过document.documentElement
获取。后者构成了树结构的根节点(root node),其他 HTML 标签节点都是它的下级节点。
除了根节点,其他节点都有三种层级关系。
- 父节点关系(parentNode):直接的那个上级节点
- 子节点关系(childNodes):直接的下级节点
- 同级节点关系(sibling):拥有同一个父节点的节点
二、Node 接口
所有 DOM 节点对象都继承了 Node 接口(所有DOM继承了EventTarget接口),拥有一些共同的属性和方法。这是 DOM 操作的基础。
1、属性
nodeType
返回一个整数值,表示节点的类型
节点 | 类型 | 例子 |
---|---|---|
ELEMENT_NODE 元素节点 | 1 | <h1 class="heading">W3School</h1> |
ATTRIBUTE_NODE 属性节点 | 2 | class = "heading" (弃用) |
TEXT_NODE 文本节点 | 3 | W3School |
COMMENT_NODE 注释节点 | 8 | <!-- 这是注释 --> |
DOCUMENT_NODE 文档节点 | 9 | HTML 文档本身(<html> 的父) |
DOCUMENT_TYPE_NODE 文档类型节点 | 10 | <!Doctype html> |
nodeName
返回节点的名称
不同节点的nodeName
属性值如下。
- 文档节点(document):
#document
- 元素节点(element):大写的标签名
- 属性节点(attr):属性的名称
- 文本节点(text):
#text
- 文档片断节点(DocumentFragment):
#document-fragment
- 文档类型节点(DocumentType):文档的类型
- 注释节点(Comment):
#comment
nodeValue
返回一个字符串,表示当前节点本身的文本值,该属性可读写
只有文本节点(text)、注释节点(comment)和属性节点(attr)有文本值,因此这三类节点的nodeValue
可以返回结果,其他类型的节点一律返回null
1 |
|
textContent
返回当前节点和它的所有后代节点的文本内容。自动忽略当前节点内部的 HTML 标签,返回所有文本内容。
1 |
|
该属性是可读写的,设置该属性的值,会用一个新的文本节点,覆盖掉所有原来的子节点,而且自动对HTML标签转义(即不会当做标签处理)
对于文本节点(text)、注释节点(comment)和属性节点(attr),textContent
属性的值与nodeValue
属性相同
对于其他类型的节点,该属性会将每个子节点(不包括注释节点)的内容连接在一起返回。如果一个节点没有子节点,则返回空字符串。
如果要读取整个文档的内容,可以使用document.documentElement.textContent
父子兄弟节点属性
属性 | 说明 |
---|---|
nextSibling | 返回紧跟在当前节点后面的第一个同级节点,如果没有返回 null 该属性还包括文本节点和注释节,因此如果当前节点后面有空格,该属性会返回一个文本节点,内容为空格,例一 |
previousSibling | 返回当前节点前面的、距离最近的一个同级节点。如果当前节点前面没有同级节点,则返回null |
parentNode | 返回当前节点的父节点 对于一个节点来说,它的父节点只可能是三种类型:元素节点、文档节点、文档片段节点 |
parentElement | 返回当前节点的父元素节点。如果当前节点没有父节点,或者父节点类型不是元素节点,则返回null |
firstChild | 返回当前节点的第一个子节点,如果当前节点没有子节点,则返回null 返回的节点除了元素节点,还可能是文本节点或注释节点,例二 |
lastChild | 返回当前节点的最后一个子节点,如果当前节点没有子节点,则返回null |
childNodes | 返回一个类似数组的对象(NodeList 集合),成员包括当前节点的所有子节点,包括元素节点、文本节点、注释节点NodeList 对象是一个动态集合,一旦子节点发生变化,立刻会反映在返回结果之中。 |
例一
1 |
|
例二
1 |
|
2、方法
appendChild()
接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点。该方法的返回值就是插入文档的子节点。
如果参数节点是 DOM 已经存在的节点,appendChild()
方法会将其从原来的位置,移动到新位置
1 |
|
如果appendChild()
方法的参数是DocumentFragment
节点,那么插入的是DocumentFragment
的所有子节点,而不是DocumentFragment
节点本身。返回值是一个空的DocumentFragment
节点。一次性插入,减少DOM操作
insertBefore()
用于将某个节点插入父节点内部的指定位置。接受两个参数,第一个参数是所要插入的节点newNode
,第二个参数是父节点parentNode
内部的一个子节点referenceNode
。newNode
将插在referenceNode
这个子节点的前面。返回值是插入的新节点newNode
。
如果insertBefore
方法的第二个参数为null
,则新节点将插在当前节点内部的最后位置,即变成最后一个子节点。
如果所要插入的节点是当前 DOM 现有的节点,则该节点将从原有的位置移除,插入新的位置。
如果要插入的节点是DocumentFragment
类型,那么插入的将是DocumentFragment
的所有子节点,而不是DocumentFragment
节点本身。返回值将是一个空的DocumentFragment
节点。
removeChild()
接受一个子节点作为参数,用于从当前节点移除该子节点。返回值是移除的子节点
被移除的节点依然存在于内存之中,但不再是 DOM 的一部分。所以,一个节点移除以后,依然可以使用它,比如插入到另一个节点下面。
其它方法
方法 | 说明 |
---|---|
hasChildNodes() | 返回一个布尔值,表示当前节点是否有子节点。 注意,子节点包括所有类型的节点,并不仅仅是元素节点 |
cloneNode() | 用于克隆一个节点。它接受一个布尔值作为参数,表示是否同时克隆子节点。返回值是一个克隆的新节点 注意:1.克隆一个节点,会拷贝该节点的所有属性,但是会丧失 addEventListener 方法和on- 属性2.,该方法返回的节点不在文档之中,即没有任何父节点,必须使用诸如 Node.appendChild 这样的方法添加到文档之中3.克隆一个节点之后,DOM 有可能出现两个有相同 id 属性,这时应该修改其中一个元素的id 属性 |
replaceChild() | 用于将一个新的节点,替换当前节点的某一个子节点 接受两个参数,第一个参数 newChild 是用来替换的新节点,第二个参数oldChild 是将要替换走的子节点。返回值是替换走的那个节点oldChild |
contains() | 返回一个布尔值,表示参数节点是否是当前节点的本身、或子节点、或后代节点 |
normalize() | 用于清理当前节点内部的所有文本节点(text) 它会去除空的文本节点,并且将毗邻的文本节点合并成一个,也就是说不存在空的文本节点,以及毗邻的文本节点 |
getRootNode() | 返回当前节点所在文档的根节点document ,与ownerDocument 属性的作用相同 |
1 |
|
三、NodeList 和 HTMLCollection
节点都是单个对象,有时需要一种数据结构,能够容纳多个节点。DOM 提供两种节点集合,用于容纳多个节点:NodeList
和HTMLCollection
。两者主要区别是,NodeList
可以包含各种类型的节点,HTMLCollection
只能包含 HTML 元素节点。
共同点:
- 类数组对象,能够通过下标直接访问,可以使用 length属性,可以遍历,但是不具备其它数组方法
1、NodeList
可以使用length
属性和forEach
方法。但是,它不是数组,不能使用pop
或push
之类数组特有的方法
通过以下方法可以得到NodeList
实例。
Node.childNodes
document.querySelectorAll()
等节点搜索方法
注意,NodeList 实例可能是动态集合,也可能是静态集合。目前,只有Node.childNodes
返回的是一个动态集合,其他的 NodeList 都是静态集合。
1 |
|
keys、values、entries方法
1 |
|
2、HTMLCollection
节点对象的集合,只能包含元素节点(element),不能包含其他类型的节点,不能使用 forEach方法,只能用 for循环遍历
返回HTMLCollection
实例的,主要是一些Document
对象的集合属性,比如document.links
、document.forms
、document.images
等。
HTMLCollection
实例都是动态集合,节点的变化会实时反映在集合中。
如果元素节点有id
或name
属性,那么HTMLCollection
实例上面,可以使用id
属性或name
属性引用该节点元素。如果没有对应的节点,则返回null
。
1 |
|
HTMLCollection.prototype.namedItem()
参数是一个字符串,表示id
属性或name
属性的值,返回对应的元素节点
1 |
|
四、ParentNode 和 ChildNode
节点对象除了继承 Node 接口以外,还拥有其他接口。ParentNode
接口表示当前节点是一个父节点,提供一些处理子节点的方法。ChildNode
接口表示当前节点是一个子节点,提供一些相关方法
感觉这两个node都是HTMLElement,和HTMLCollection的子元素有相同的属性和接口
1、ParentNode 接口
如果当前节点是父节点,就会混入了(mixin)ParentNode
接口。由于只有元素节点(element)、文档节点(document)和文档片段节点(documentFragment)拥有子节点,因此只有这三类节点会拥有ParentNode
接口
属性/方法 | 说明 |
---|---|
children | 返回一个HTMLCollection 实例,成员是当前节点的所有元素子节点,不包含其它类型子节点。该属性只读。是动态集合 |
firstElementChild | 当前节点的第一个元素子节点,若没有则返回null |
lastElementChild | 当前节点的最后一个元素子节点,若没有则返回null |
childElementCount | 所有元素子节点的数目 |
append() | 为当前节点追加一个或多个子节点,位置是最后一个元素子节点的后面。 不仅可以填加元素子节点,还可以添加文本子节点,该方法没有返回值 |
prepend() | 为当前节点追加一个或多个子节点,位置是第一个元素子节点的前面,没有返回值 |
1 |
|
2、ChildNode 接口
如果一个节点有父节点,那么该节点就拥有了ChildNode
接口
属性/方法 | 说明 |
---|---|
remove() | 用于从父节点移除当前节点 |
before() | 用于在当前节点的前面,插入一个或多个同级节点。两者拥有相同的父节点,不仅可以插入元素,还可以插入文本节点 |
after() | 用于在当前节点的后面,插入一个或多个同级节点,两者拥有相同的父节点 |
replaceWith() | 使用参数节点,替换当前节点。参数可以是元素节点,也可以是文本节点 |
1 |
|
五、Document 节点
document
节点对象代表整个文档,每张网页都有自己的document
对象。window.document
属性就指向这个对象。只要浏览器开始载入 HTML 文档,该对象就存在了,可以直接使用。
document的原型继承如下:
1 |
|
document
对象有不同的办法可以获取。
- 正常的网页,直接使用
document
或window.document
。 iframe
框架里面的网页,使用iframe
节点的contentDocument
属性。- Ajax 操作返回的文档,使用
XMLHttpRequest
对象的responseXML
属性。 - 内部节点的
ownerDocument
属性。
document
对象继承了EventTarget
接口和Node
接口,并且混入(mixin)了ParentNode
接口。这意味着,这些接口的方法都可以在document
对象上调用。除此之外,document
对象还有很多自己的属性和方法
1、属性
下表列举部分常见的属性
属性 | 说明 |
---|---|
document.doctype | 指向<DOCTYPE> 节点,即文档类型节点 |
documentElement | 返回当前文档的根元素节点(root),一般是<html> 节点 |
activeElement | 返回获得当前焦点(focus)的 DOM 元素,如果当前没有焦点元素,返回<body> 元素或null |
节点集合属性 | 说明 |
---|---|
document.links | 返回当前文档所有设定了href 属性的<a> 及<area> 节点 |
forms | 返回所有<form> 表单节点 |
images | 返回页面所有<img> 图片节点 |
scripts | 返回所有<script> 节点 |
styleSheets | 返回文档内嵌或引入的样式表集合 |
文档静态信息属性 | 说明 |
---|---|
document.documentURI | 返回一个字符串,表示当前文档的网址,继承自Document 接口,可用于所有文档 |
document.URL | 返回一个字符串,表示当前文档的网址,继承自HTMLDocument 接口,只能用于 HTML 文档如果文档的锚点( #anchor )变化,这两个属性都会跟着变化 |
domain | 返回当前文档的域名,不包含协议和端口 比如:http://www.example.com:80/hello.html,返回:www.example.com。补充一 |
lastModified | 返回一个字符串,表示当前文档最后修改的时间,需要转换为Date类型后才能相互比较 |
characterSet | 返回当前文档的编码,比如UTF-8 、ISO-8859-1 |
referrer | 返回一个url字符串,表示当前文档的访问者来自哪里。如果无法获取或者没有来源,返回空字符串 |
补充一,
document.domain
基本上是一个只读属性,只有一种情况除外。次级域名的网页,可以把document.domain
设为对应的上级域名。比如,当前域名是a.sub.example.com
,则document.domain
属性可以设置为sub.example.com
,也可以设为example.com
。修改后,document.domain
相同的两个网页,可以读取对方的资源,比如设置的 Cookie。设置
document.domain
会导致端口被改成null
。因此,如果通过设置document.domain
来进行通信,双方网页都必须设置这个值,才能保证端口相同。
文档状态属性 | 说明 |
---|---|
document.hidden | 返回一个布尔值,表示当前页面是否可见。如果窗口最小化、浏览器切换了 Tab,都会导致导致页面不可见,使得document.hidden 返回true |
visibilityState | 返回文档的可见状态。范围为4个值:visible (页面可见)、hidden (页面不可见)、prerender (页面处于正在渲染状态)、unloaded (页面从内存里面卸载了) |
readyState | 返回当前文档的状态。范围为3个值:loading :加载 HTML 代码阶段(尚未完成解析)、interactive :加载外部资源阶段、complete :加载完成每次状态变化都会触发一个 readystatechange 事件 |
designMode | 控制当前文档是否可编辑。该属性只有两个值on 和off ,默认值为off 。一旦设为on ,用户就可以编辑整个文档的内容 |
2、方法
获取DOM节点的方法
1 |
|
1 |
|
以上两种方法不支持 CSS 伪元素和伪类的选择器。这两个方法除了定义在document
对象上,还定义在元素节点上,即在元素节点上也可以调用。
拓展:CSS选择器的组合方法
多个选择器通过逗号
,
相连,表示同时选中各个选择器1
h1,h2,p { } 表示同时选中h1,h2和p
多个类名之间没有间隔,连接在一起,表示同时具有这些类的所有元素
1
.class1.class2 表示选择同时具有class1和class2类的所有元素
多个选择器之间用空格隔开,表示从前到后的深入关系
1
.class1 .class2 p 表示选择class1类元素里面的 class2类元素里面的 所有p标签
创建DOM节点的方法
1 |
|
六、Element 节点
Element
节点对象对应网页的 HTML 元素。每一个 HTML 元素,在 DOM 树上都会转化成一个Element
节点对象。
Element
对象继承了Node
接口,因此Node
的属性和方法在Element
对象都存在。
此外,不同的 HTML 元素对应的元素节点是不一样的,浏览器使用不同的构造函数,生成不同的元素节点,比如<a>
元素的构造函数是HTMLAnchorElement()
,<button>
是HTMLButtonElement()
。因此,元素节点不是一种对象,而是许多种对象,这些对象除了继承Element
对象的属性和方法,还有各自独有的属性和方法。
Element元素节点的原型继承关系如下:
1 |
|
1、实例属性
元素节点的属性
特性相关的属性
属性 | 说明 |
---|---|
Element.id | 指定元素的id 属性 |
tagName | 指定元素的大写标签名,与nodeName 属性的值相等 |
dir | 读写当前元素的文字方向 |
accessKey | 用于读写分配给当前元素的快捷键 |
tabIndex | 当前元素在 Tab 键遍历时的顺序。该属性可读写 |
title | 用来读写当前元素的 HTML 属性title ,通常用来指定,鼠标悬浮时弹出的文字提示框 |
1 |
|
状态相关的属性
属性 | 说明 |
---|---|
hidden | 一个布尔值,表示当前元素的hidden 属性,用来控制当前元素是否可见,可读写与 CSS 设置是互相独立的,CSS 的设置高于 Element.hidden |
contentEditable | 字符串(’true’、’false’、’inherit’),元素的内容是否可以编辑,可读写 |
isContentEditable | 同上,只读 |
attributes | 类数组对象,包含当前元素节点所有的属性节点 |
className | 字符串,读写当前元素节点的class 属性,每个class 之间用空格分割 |
classList | 类数组对象,包含所有类名。具有多种方法:add、remove、contains、toString、toggle |
dataset | 网页元素可以自定义data- 属性,用来添加数据,Element.dataset 属性返回一个对象,可以从这个对象读写data- 属性 |
innerHTML | 返回一个字符串,等同于该元素包含的所有 HTML 代码,可读写。 返回实体符号(如 < )时,innerHTML会将它转为实体形式(& )注意:如果赋值的文本中包含 <script> 标签,虽然可以生成script节点,但是不会执行 |
outerHTML | 返回一个字符串,表示当前元素节点的所有 HTML 代码,包括该元素本身和所有子元素,可读写 注意,如果一个节点没有父节点,设置 outerHTML 属性会报错 |
Element.clientHeight | 整数值,表示元素节点的 CSS 高度(单位像素),只对块级元素生效,对于行内元素返回0 。如果块级元素没有设置 CSS 高度,则返回实际高度 包括padding,不包括border和margin,去除水平滚动条高度 |
clientWidth | 返回元素节点的 CSS 宽度,同样只对块级元素有效,去除滚动条宽度 |
clientLeft | 元素左边框的宽度,行内元素为0 |
scrollHeight | 当前元素的总高度(px),包括溢出部分 |
scrollWidth | 当前元素的总宽度(px) |
scrollLeft | 当前元素的水平滚动条向右侧滚动的像素数量 |
scrollTop | 当前元素的垂直滚动条向下滚动的像素数量 |
style | 用来读写该元素的行内样式信息 |
children | HTMLCollection实例,包括当前元素节点的所有子元素,只包含元素节点,不包含其它类型节点 |
childElementCount | 当前元素节点包含的子元素节点的个数 |
firstElementChild | 当前元素的第一个元素子节点 |
lastElementChild | 最后一个元素子节点 |
nextElementSibling | 前一个同级元素节点 |
previousElementSibling | 后一个同级元素节点 |
1 |
|
2、实例方法
元素节点的方法
属性相关
元素节点提供六个方法,用来操作属性。
getAttribute()
:读取某个属性的值getAttributeNames()
:返回当前元素的所有属性名setAttribute()
:写入属性值hasAttribute()
:某个属性是否存在hasAttributes()
:当前元素是否有属性removeAttribute()
:删除属性
获取节点相关
- querySelector(),接受css选择器作为参数,返回第一个匹配的子元素,无法选中伪元素和伪类
- querySelectorAll(),接受css选择器作为参数,返回所有匹配的子元素(NodeList对象),若参数为
*
,返回所有子元素 - getElementsByTagName()
- getElementsByClassName()
- closest(),接受一个 CSS 选择器作为参数,返回匹配该选择器的、最接近当前节点的一个祖先节点(包括当前节点本身)
- matches(),返回一个布尔值,表示当前元素是否匹配给定的 CSS 选择器
事件相关
- addEventListener()
- removeEventListener()
- dispatchEvent()
scrollIntoView()
滚动当前元素,进入浏览器的可见区域,类似于设置window.location.hash
的效果
1 |
|
getBoundingClientRect()
返回一个对象,提供当前元素节点的大小、位置等信息,基本上就是 CSS 盒状模型的所有信息,返回对象的参数如下;
x
:元素左上角相对于视口的横坐标y
:元素左上角相对于视口的纵坐标height
:元素高度width
:元素宽度top
:元素顶部相对于视口的纵坐标,与y
属性相等bottom
:元素底部相对于视口的纵坐标(等于y + height
)
remove()
继承自 ChildNode 接口,用于将当前元素节点从它的父节点移除
focus() 和 blur()
用于将当前页面的焦点,转移到指定元素上。
1 |
|
七、属性的操作
HTML 元素包括标签名和若干个键值对,这个键值对就称为“属性”(attribute)
1 |
|
HTML 元素的属性名是大小写不敏感的,但是 JavaScript 对象的属性名是大小写敏感的。JavaScript对象的属性名采取驼峰格式,如onClick
Element.attributes
类数组对象,包含当前元素标签的所有属性节点对象
1 |
|
操作的方法
元素节点提供六个方法,用来操作属性。
getAttribute()
,返回当前元素节点的指定属性。如果指定属性不存在,则返回null
getAttributeNames()
,返回一个数组(而不是类数组),成员是当前元素的所有属性的名字setAttribute()
,用于为当前元素节点新增属性。如果同名属性已存在,则相当于编辑已存在的属性hasAttribute()
,返回一个布尔值,表示当前元素节点是否包含指定属性hasAttributes()
,返回一个布尔值,表示当前元素是否有属性removeAttribute()
,移除指定属性。该方法没有返回值
dataset属性
有时,需要在HTML元素上附加数据,解决方法是,使用标准提供的data-*
属性
在HTML中,data-
后面的属性名有限制,只能是:小写字母、短横线-
、点.
、冒号:
、下划线_
与JavaScript对象的转换规则为:驼峰(JS对象)—— kebab-case(HTML),如:data-hello-world
对应 dataset.helloWorld
删除一个data-*
属性,可以直接使用delete
命令
1 |
|
八、Text 节点
文本节点(Text
)代表元素节点(Element
)和属性节点(Attribute
)的文本内容。
通常文本节点作为元素节点的第一个子节点
1 |
|
文本节点除了继承Node
接口,还继承了CharacterData
接口。Node
接口的属性和方法请参考《Node 接口》一章,这里不再重复介绍了,以下的属性和方法大部分来自CharacterData
接2
属性 | 说明 |
---|---|
data | 等同于nodeValue 属性,用来设置或读取文本节点的内容 |
wholeText | 将当前文本节点与毗邻的文本节点,作为一个整体返回 |
length | 返回当前文本节点的文本长度 |
nextElementSibling | 返回紧跟在当前文本节点后面的那个同级元素节点 |
1 |
|
方法
appendData()
:在Text
节点尾部追加字符串。deleteData()
:删除Text
节点内部的子字符串,第一个参数为子字符串开始位置,第二个参数为子字符串长度。insertData()
:在Text
节点插入字符串,第一个参数为插入位置,第二个参数为插入的子字符串。replaceData()
:用于替换文本,第一个参数为替换开始位置,第二个参数为需要被替换掉的长度,第三个参数为新加入的字符串。subStringData()
:用于获取子字符串,第一个参数为子字符串在Text
节点中的开始位置,第二个参数为子字符串长度。
1 |
|
九、CSS操作
1、内联CSS操作
- 使用元素节点的
setAttribute()
等方法,最简单 - 使用元素节点的
style
属性(它部署了CSSStyleDeclaration接口),可以读写个别属性
1 |
|
2、增删类名修改样式
通过修改元素节点的className或classList属性,来达到修改样式的目的
- className,字符串,读写当前元素节点的
class
属性,每个class
之间用空格分割 - classList,类数组对象,包含所有类名。具有多种方法:add、remove、contains、toString、toggle
1 |
|
3、window.getComputedStyle()
行内样式(inline style)具有最高的优先级,改变行内样式,通常会立即反映出来。但是,网页元素最终的样式是综合各种规则计算出来的。因此,如果想得到元素实际的样式,只读取行内样式是不够的。
window.getComputedStyle
- 参数一:节点对象,要获取样式的目标对象
- 参数二:(可选)伪元素(比如
:before
、:after
、:first-line
、:first-letter
等) - 返回值:CSS 规则叠加后的的最终规则,一个 CSSStyleDeclaration 实例
4、CSS样式表操作
StyleSheet
接口代表网页的一张样式表,包括<link>
元素加载的样式表和<style>
元素内嵌的样式表
document
对象的styleSheets
属性,可以返回当前页面的所有StyleSheet
实例(即所有样式表)。它是一个类似数组的对象
更多细节,请阅读原文:DOM - CSS 操作 - 《阮一峰 JavaScript 教程》 - 书栈网 · BookStack
十、DocumentFragment 节点
DocumentFragment
节点代表一个文档的片段,本身就是一个完整的 DOM 树形结构。它没有父节点,但是可以插入任意数量的子节点。它不属于当前文档,操作DocumentFragment
节点,要比直接操作 DOM 树快得多。
一般用于构建一个 DOM 结构,然后插入当前文档。
1 |
|
DocumentFragment
节点本身不能被插入当前文档,是它的所有子节点插入当前文档,一旦DocumentFragment
节点被添加进当前文档,它自身就变成了空节点。
DocumentFragment
节点对象没有自己的属性和方法,全部继承自Node
节点和ParentNode
接口。也就是说,DocumentFragment
节点比Node
节点多出以下四个属性。
children
:返回一个动态的HTMLCollection
集合对象,包括当前DocumentFragment
对象的所有子元素节点。firstElementChild
:返回当前DocumentFragment
对象的第一个子元素节点,如果没有则返回null
。lastElementChild
:返回当前DocumentFragment
对象的最后一个子元素节点,如果没有则返回null
。childElementCount
:返回当前DocumentFragment
对象的所有子元素数量。
经过实践发现,DocumentFrame好像并不能处理所有类型的元素节点,在借助它往DOM的div标签插入一组img时,并没有成功!
十一、Mutation Observer API
Mutation Observer API 用来监视 DOM 变动。DOM 的任何变动,比如节点的增减、属性的变动、文本内容的变动,这个 API 都可以得到通知。
具体操作请阅读:DOM - Mutation Observer API - 《阮一峰 JavaScript 教程》 - 书栈网 · BookStack
目前还没有遇到此类需求,所以暂时只做简单了解
十二、innerText和textContent的区别
两个属性并非html5的规范属性,而是各个浏览器厂商自己实现的。
- innerText的值近似于浏览器的显示效果,textContent近似于于代码的显示效果
- 如果一个元素之间包含了script标签或者style标签,innerText是获取不到这两个元素之间的文本的,而textContent可以
- textContent会把空标签解析成换行(几个空标签就是几行),innerText只会把block元素类型的空标签解析换行,并且如果是多个的话仍看成是一个,而inline类型的原素则解析成空格
- innerText的设置会引发浏览器的回流操作,而textContent则不一定会