目录

🍕 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(浏览器对象模型)、 各种浏览器函数: setTimeoutalertlocation 等。

https://html.spec.whatwg.org (opens new window)。它采用了 DOM 规范,并使用了许多其他属性和方法对其进行了扩展。

# HTML DOM 树

  • 通过 DOM 接口可以改变网页的内容、结构和样式

    • 文档:一个页面就是一个文档,DOM 中使用 document 表示

    • 元素:页面中的所有标签都是元素,DOM 中使用 element 表示

    • 节点:网页中的所有内容都是节点(标签、属性、文本、注释等)DOM 中使用 node 表示;

  • HTML 中的所有内容,甚至注释,都会成为 DOM 的一部分。

  • 当网页被加载时,浏览器会创建页面的 DOM。HTML DOM 会被构造为对象的树:

    img

# 遍历 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>
1
2
3
4
5
6
7
for(let i = 0; i < document.body.childNodes.length; i++) {
  console.log(document.body.childNodes[i])
}
1
2
3

<body> 元素的子孙元素不仅包含直接的子元素 <div><ul> ,还包含像 <li><ul> 的子元素)和 <b><li> 的子元素)整个子树。

  • 子节点:对应的是 直系 的子元素。例如 <body><html> 的子节点元素。

  • 子孙元素:嵌套在给定元素中的所有元素,包括子元素,以及子元素的子元素等。

  • 使用 childNodes 获取所有的 子孙元素。(获取的结果是一个 类数组 集合,可以迭代,但是不能是有数组方法,要使用数组方法需要转换为数组;并且是 只读的,不能通过它 替换节点)(最好使用 for … of 迭代(使用 for…in 迭代的都是可枚举属性))

  • 使用 firstChildlastChild 属性访问第一个和最后一个子元素。

# 父节点和兄弟节点

🌰 例子:

<html>
  <head>...</head>
	<body>...</body>
</html>
1
2
3
4
console.log(document.body.parentNode === document.documentElement) // true
console.log(document.head.nextSibling) // HTMLBodyElement
console.log(document.body.previousSibling) // HTMLHeadElement
1
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名称');
    
    1

    id 必须是唯一的。在文档中,只能有一个元素带有给定的 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 选择器 匹配。它返回 truefalse

通常用于在遍历元素时筛选找到的元素对象。

🌰 例子:

<a href="http://example.com/file.zip">...</a>
<a href="http://ya.ru">...</a>
1
2
for (let elem of document.body.children) {
  if (elem.matches('a[href$="zip"]')) {
    alert("The archive reference: " + elem.href );
  }
}
1
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>
1
2
3
4
5
6
let chapter = document.querySelector('.chapter') // LI

chapter.closet('.book') // UL
chapter.closet('.contents') // DIV
chapter.closet('h1') // null
1
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>
1
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>
1
2
3
4
5
6
7
8
9
10
11
12
📢 上次更新: 2022/09/02, 10:18:16