DOM树
文档对象模型(DOM), 每个 HTML 标签都是一个对象
标签被称为 元素节点
元素内的文本形成 文本节点
**
只有两个顶级排除项:
- 由于历史原因,
<head>
之前的空格和换行符均被忽略。 - 如果我们在
</body>
之后放置一些东西,那么它会被自动移动到body
内,并处于body
中的最下方,因为 HTML 规范要求所有内容必须位于<body>
内。所以</body>
之后不能有空格。
如果浏览器遇到格式不正确的 HTML,它会在形成 DOM 时自动更正它。
表格永远有 <tbody>
对于 HTML:<table id="table"><tr><td>1</td></tr></table>
**
一共有 12 种节点类型。实际上,我们通常用到的是其中的 4 种:
document
— DOM 的“入口点”。- 元素节点 — HTML 标签,树构建块。
- 文本节点 — 包含文本。
- 注释 — 有时我们可以将一些信息放入其中,它不会显示,但 JS 可以从 DOM 中读取它。
一个查看DOM结构的工具
http://software.hixie.ch/utilities/js/live-dom-viewer/
与控制台交互
步骤如下:
- 在元素(Elements)选项卡中选择第一个
<li>
。 - 按下 Esc — 它将在元素(Elements)选项卡下方打开控制台(Console)。
现在最后选中的元素可以通过 $0
来进行操作
我们可以对它们执行一些命令。例如,$0.style.background = 'red'
使选定的列表项(list item)变成红色
遍历DOM
对 DOM 的所有操作都是以 document
对象开始。它是 DOM 的主“入口点”。从它我们可以访问任何节点。
最顶层的树节点可以直接作为 document
的属性来使用:
= document.documentElement
最顶层的 document 节点是 document.documentElement
。这是对应 <html>
标签的 DOM 节点。
= document.body
另一个被广泛使用的 DOM 节点是 <body>
元素 — document.body
。
= document.head<head>
标签可以通过 document.head
访问
childNodes
集合列出了所有子节点,包括文本节点firstChild
和 lastChild
属性是访问第一个和最后一个子元素的快捷方式。
它们只是简写。如果元素存在子节点,那么下面的脚本运行结果将是 true:
elem.childNodes[0] === elem.firstChild
elem.childNodes[elem.childNodes.length - 1] === elem.lastChild
这里还有一个特别的函数 elem.hasChildNodes()
用于检查节点是否有子节点
childNodes
看起来就像一个数组。但实际上它并不是一个数组,而是一个 集合 — 一个类数组的可迭代对象。
可以使用 for..of
来迭代它
无法使用数组的方法,因为它不是一个数组
兄弟节点和父节点
// <body> 的父节点是 <html>
alert( document.body.parentNode === document.documentElement ); // true
// <head> 的后一个是 <body>
alert( document.head.nextSibling ); // HTMLBodyElement
// <body> 的前一个是 <head>
alert( document.body.previousSibling ); // HTMLHeadElement
纯元素节点
这些链接和我们在上面提到过的类似,只是在词中间加了 Element
:
children
— 仅那些作为元素节点的子代的节点。firstElementChild
,lastElementChild
— 第一个和最后一个子元素。previousElementSibling
,nextElementSibling
— 兄弟元素。parentElement
— 父元素。
document
不是一个元素节点
搜索
如果一个元素有 id 特性(attribute),那我们就可以使用 document.getElementById(id) 方法获取该元素
<div id="elem"></div>
// 获取该元素
let elem = document.getElementById('elem');
// 将该元素背景改为红色
elem.style.background = 'red';
还可以只使用id
<div id="elem1"></div>
// elem1 是对带有 id="elem1" 的 DOM 元素的引用
elem1.style.background = 'red';
在实际开发中,document.getElementById
是首选方法
elem.querySelectorAll(css)
,返回 elem
中与给定 CSS 选择器匹配的所有元素
<ul>
<li>The</li>
<li>test</li>
</ul>
<ul>
<li>has</li>
<li>passed</li>
</ul>
<script>
let elements = document.querySelectorAll('ul > li:last-child');
for (let elem of elements) {
alert(elem.innerHTML); // "test", "passed"
}
</script>
elem.querySelector(css)
调用会返回给定 CSS 选择器的第一个元素
elem.matches(css)
不会查找任何内容,它只会检查 elem
是否与给定的 CSS 选择器匹配。它返回 true
或 false
elem.closest(css)
方法会查找与 CSS 选择器匹配的最近的祖先
getElementsBy* , 返回一个集合
elem.getElementsByTagName(tag)
查找具有给定标签的元素,并返回它们的集合。tag
参数也可以是对于“任何标签”的星号"*"
。elem.getElementsByClassName(className)
返回具有给定CSS类的元素。document.getElementsByName(name)
返回在文档范围内具有给定name
特性的元素。很少使用。
如果 elemB
在 elemA
内(elemA
的后代)或者 elemA==elemB
,elemA.contains(elemB)
将返回 true。