DOM树

文档对象模型(DOM), 每个 HTML 标签都是一个对象
标签被称为 元素节点
元素内的文本形成 文本节点
**
只有两个顶级排除项:

  1. 由于历史原因,<head> 之前的空格和换行符均被忽略。
  2. 如果我们在 </body> 之后放置一些东西,那么它会被自动移动到 body 内,并处于 body 中的最下方,因为 HTML 规范要求所有内容必须位于 <body> 内。所以 </body> 之后不能有空格。

如果浏览器遇到格式不正确的 HTML,它会在形成 DOM 时自动更正它。
表格永远有 <tbody>
对于 HTML:
<table id="table"><tr><td>1</td></tr></table>
image.png
**
一共有 12 种节点类型。实际上,我们通常用到的是其中的 4 种:

  1. document — DOM 的“入口点”。
  2. 元素节点 — HTML 标签,树构建块。
  3. 文本节点 — 包含文本。
  4. 注释 — 有时我们可以将一些信息放入其中,它不会显示,但 JS 可以从 DOM 中读取它。

一个查看DOM结构的工具
http://software.hixie.ch/utilities/js/live-dom-viewer/

与控制台交互
步骤如下:

  • 在元素(Elements)选项卡中选择第一个 <li>
  • 按下 Esc — 它将在元素(Elements)选项卡下方打开控制台(Console)。

现在最后选中的元素可以通过 $0 来进行操作
我们可以对它们执行一些命令。例如,$0.style.background = 'red' 使选定的列表项(list item)变成红色
image.png

遍历DOM

对 DOM 的所有操作都是以 document 对象开始。它是 DOM 的主“入口点”。从它我们可以访问任何节点。
最顶层的树节点可以直接作为 document 的属性来使用:
= document.documentElement
最顶层的 document 节点是 document.documentElement。这是对应 <html> 标签的 DOM 节点。
= document.body
另一个被广泛使用的 DOM 节点是 <body> 元素 — document.body
= document.head
<head> 标签可以通过 document.head 访问

childNodes 集合列出了所有子节点,包括文本节点
firstChildlastChild 属性是访问第一个和最后一个子元素的快捷方式。
它们只是简写。如果元素存在子节点,那么下面的脚本运行结果将是 true:

  1. elem.childNodes[0] === elem.firstChild
  2. elem.childNodes[elem.childNodes.length - 1] === elem.lastChild

这里还有一个特别的函数 elem.hasChildNodes() 用于检查节点是否有子节点

childNodes 看起来就像一个数组。但实际上它并不是一个数组,而是一个 集合 — 一个类数组的可迭代对象。
可以使用 for..of 来迭代它
无法使用数组的方法,因为它不是一个数组

兄弟节点和父节点

  1. // <body> 的父节点是 <html>
  2. alert( document.body.parentNode === document.documentElement ); // true
  3. // <head> 的后一个是 <body>
  4. alert( document.head.nextSibling ); // HTMLBodyElement
  5. // <body> 的前一个是 <head>
  6. alert( document.body.previousSibling ); // HTMLHeadElement

纯元素节点
这些链接和我们在上面提到过的类似,只是在词中间加了 Element

  • children — 仅那些作为元素节点的子代的节点。
  • firstElementChildlastElementChild — 第一个和最后一个子元素。
  • previousElementSiblingnextElementSibling — 兄弟元素。
  • parentElement — 父元素。

document 不是一个元素节点

搜索

如果一个元素有 id 特性(attribute),那我们就可以使用 document.getElementById(id) 方法获取该元素

  1. <div id="elem"></div>
  1. // 获取该元素
  2. let elem = document.getElementById('elem');
  3. // 将该元素背景改为红色
  4. elem.style.background = 'red';

还可以只使用id

  1. <div id="elem1"></div>
  1. // elem1 是对带有 id="elem1" 的 DOM 元素的引用
  2. elem1.style.background = 'red';

在实际开发中,document.getElementById 是首选方法

elem.querySelectorAll(css),返回 elem 中与给定 CSS 选择器匹配的所有元素

  1. <ul>
  2. <li>The</li>
  3. <li>test</li>
  4. </ul>
  5. <ul>
  6. <li>has</li>
  7. <li>passed</li>
  8. </ul>
  9. <script>
  10. let elements = document.querySelectorAll('ul > li:last-child');
  11. for (let elem of elements) {
  12. alert(elem.innerHTML); // "test", "passed"
  13. }
  14. </script>

elem.querySelector(css) 调用会返回给定 CSS 选择器的第一个元素

elem.matches(css) 不会查找任何内容,它只会检查 elem 是否与给定的 CSS 选择器匹配。它返回 truefalse
elem.closest(css) 方法会查找与 CSS 选择器匹配的最近的祖先

getElementsBy* , 返回一个集合

  • elem.getElementsByTagName(tag) 查找具有给定标签的元素,并返回它们的集合。tag 参数也可以是对于“任何标签”的星号 "*"
  • elem.getElementsByClassName(className) 返回具有给定CSS类的元素。
  • document.getElementsByName(name) 返回在文档范围内具有给定 name 特性的元素。很少使用。

如果 elemBelemA 内(elemA 的后代)或者 elemA==elemBelemA.contains(elemB) 将返回 true。