🍕 JavaScript DOM 树
关于 window
对象:
- 是 JavaScript 代码中的 全局对象。
- 代表 浏览器窗口。提供了 控制它的方法。
关于 DOM 与 BOM:
DOM: 文档对象模型(Document Object Model),将 HTML 所有页面内容表示为可以修改的对象。
document
对象是页面的主要入口,可以利用它更改或者创建页面的内容。BOM:浏览器对象模型(Browser Object Model),表示由浏览器(主机环境)提供的用于处理文档之外的所有内容的其他对象。
🌰 例子 / 获取当前的 URL:
location.href f (confirm("Go to Wikipedia?")) { location.href = "https://wikipedia.org"; // 将浏览器重定向到另一个 URL }
1
2
3
4函数
alert/confirm/prompt
也是 BOM 的一部分:它们与文档(document)没有直接关系,但它代表了与用户通信的纯浏览器方法。
关于 HTML 规范:描述 HTML 语言(例如标签)以及 BOM(浏览器对象模型)、 各种浏览器函数: setTimeout
, alert
, location
等。
https://html.spec.whatwg.org (opens new window)。它采用了 DOM 规范,并使用了许多其他属性和方法对其进行了扩展。
# HTML DOM 树
通过 DOM 接口可以改变网页的内容、结构和样式。
文档:一个页面就是一个文档,DOM 中使用
document
表示元素:页面中的所有标签都是元素,DOM 中使用
element
表示节点:网页中的所有内容都是节点(标签、属性、文本、注释等),
DOM
中使用node
表示;
HTML 中的所有内容,甚至注释,都会成为 DOM 的一部分。
当网页被加载时,浏览器会创建页面的 DOM。HTML DOM 会被构造为对象的树:
# 遍历 DOM
DOM 允许对元素和它们中的内容做任何事。首先需要 获取对应的 DOM 对象。对 DOM 的所有操作都是以 document
对象开始。它是 DOM 的主入口点。从它可以访问任何节点。
# 顶层树节点
最顶层的树节点可以直接作为 document
的属性来使用:
<html>
通过document.documentElement
获取使用;<body>
通过document.body
获取使用;<head>
通过document.head
获取使用;
当 元素不存在时。脚本无法访问在运行时不存在的元素。例如,在
<head>
中的脚本无法访问document.body
,因为此时浏览器此时还无法读取<body>
。元素不存在时,获取为
null
。
# 子节点
🌰 例子:
<body>
<div>Begin</div>
<ul>
<li>Information</li>
</ul>
<div>End</div>
</body>
2
3
4
5
6
7
for(let i = 0; i < document.body.childNodes.length; i++) {
console.log(document.body.childNodes[i])
}
2
3
<body>
元素的子孙元素不仅包含直接的子元素<div>
和<ul>
,还包含像<li>
(<ul>
的子元素)和<b>
(<li>
的子元素)整个子树。
子节点:对应的是 直系 的子元素。例如
<body>
是<html>
的子节点元素。子孙元素:嵌套在给定元素中的所有元素,包括子元素,以及子元素的子元素等。
使用
childNodes
获取所有的 子孙元素。(获取的结果是一个 类数组 集合,可以迭代,但是不能是有数组方法,要使用数组方法需要转换为数组;并且是 只读的,不能通过它 替换节点)(最好使用for … of
迭代(使用for…in
迭代的都是可枚举属性))使用
firstChild
和lastChild
属性访问第一个和最后一个子元素。
# 父节点和兄弟节点
🌰 例子:
<html>
<head>...</head>
<body>...</body>
</html>
2
3
4
console.log(document.body.parentNode === document.documentElement) // true
console.log(document.head.nextSibling) // HTMLBodyElement
console.log(document.body.previousSibling) // HTMLHeadElement
2
3
在这个例子中, <head>
和 <body>
是兄弟节点,它们的父节点是 <body>
。 <body>
是 <head>
的下一个兄弟节点(右边), <head>
是 <body>
的上一个兄弟节点(左边)。
- 下一个兄弟节点在
nextSibling
属性中。 - 上一个兄弟节点在
previousSibling
属性中。 - 使用
parentNode
来访问父节点。
# 纯元素节点导航
要想获取 纯元素节点(代表标签和形成页面的节点),在上面的获取方法中添加 Element
:
- 作为元素节点的子节点:
chidren
; - 第一个和最后一个元素子节点:
firstElementChild,lastElementChild
; - 兄弟元素节点:
previousElementSibling
,nextElementSibling
; - 父元素节点:
parentElement
。
区分节点(Nodes) 和
Element
的使用。parentElement
属性返回的是 元素类型 的父节点,而parentNode
返回的是 任何类型 的父节点。
# 通过特定标识获取元素
# getElementBy*
根据
id
获取元素getElementById()
🌰 例子:
let idElem = document.getElementById('id名称');
1id
必须是唯一的。在文档中,只能有一个元素带有给定的id
。根据标签名获取
getElementsByTagName
:document.getElementsByTagName('标签名');
1根据元素的
class
(类名)属性值查询一组元素节点对象:document.getElementsByClassName('类名');
1
getElements*
:返回的是一个对象的集合(伪数组),想要操作当中的元素就需要遍历tagname[0]等
;getElement*
:返回的是元素对象,包括属性和方法;- 括号中的参数大小写敏感;
getElement ...
被在document
对象上调用。
# querySelector
根据 CSS 选择器去页面中查询一个元素或者一组元素:如果匹配到的元素有多个,则它会返回查询到的第一个元素。
根据指定的 选择器 返回第一个查询到的 元素对象:
document.querySelector('选择器');
1根据指定的选择器返回所有 元素对象集合(伪数组):
document.querySelectorAll('选择器');
1
- 关于 CSS 选择器:🎮 CSS 选择器;除了常见的选择器,还支持 选择器的伪类。
querySelector...
能在 元素对象上使用,完整语法为element.querySelectorAll(css)
,它返回element
中与给定 CSS 选择器匹配的所有元素。
# matches
element.matches
不搜索元素对象任何内容,只会检查 element
是否与给定的 CSS 选择器 匹配。它返回 true
或 false
。
通常用于在遍历元素时筛选找到的元素对象。
🌰 例子:
<a href="http://example.com/file.zip">...</a>
<a href="http://ya.ru">...</a>
2
for (let elem of document.body.children) {
if (elem.matches('a[href$="zip"]')) {
alert("The archive reference: " + elem.href );
}
}
2
3
4
5
# closet
element.closest(css)
方法会查找在祖先中 与选择器匹配的 祖先元素, element
自身也会被搜索。
🌰 例子:
<div class="contents">
<ul class="book">
<li class="chapter">Chapter 1</li>
<li class="chapter">Chapter 2</li>
</ul>
</div>
2
3
4
5
6
let chapter = document.querySelector('.chapter') // LI
chapter.closet('.book') // UL
chapter.closet('.contents') // DIV
chapter.closet('h1') // null
2
3
4
5
# 动态 / 静态集合
- 所有的
getElementsBy*
方法都会返回一个 实时的 集合。这样的集合始终反映的是文档的当前状态,并且在文档发生更改时会自动更新。 querySelector
返回的是一个 静态的 集合。(元素对象的固定数组)
🌰 例子:
<div>First div</div>
<script>
let divs = document.getElementsByTagName('div');
alert(divs.length); // 1
</script>
<div>Second div</div>
<script>
alert(divs.length); // 2
</script>
2
3
4
5
6
7
8
9
10
11
12
<div>First div</div>
<script>
let divs = document.querySelectorAll('div');
alert(divs.length); // 1
</script>
<div>Second div</div>
<script>
alert(divs.length); // 1
</script>
2
3
4
5
6
7
8
9
10
11
12