Skip to content

我们要使用 JS 操作 DOM 节点,首先需要知道如何获取 DOM 节点,获取 DOM 节点也可以叫做获取 DOM 对象,通常来说,我们操作的基本都是元素,所以我们获取的也基本是元素节点,所以重点应该聚焦在元素节点的获取。

在浏览器环境的全局对象中,也就是 window 对象中,有一个 document 属性,这个属性的属性值是一个对象,这个对象就是整个文档。

js
console.log(window.document);
console.log(document);//由于是window对象的属性,所以可以直接访问

![Pasted image 20240409024642](/notes-assets/02.JavaScript/6.DOM核心/assets/Pasted image 20240409024642.png)

在很早很早以前,我们会通过 document 的属性来获取节点,如下所示

  • document.body:获取 body 元素节点
  • document.head:获取 head 元素节点
  • document.links:获取页面上所有的超链接元素节点,即所有 a 元素(以伪数组的方式返回)
  • document.anchors:获取页面上所有的锚链接(具有 name 属性的 a 元素)元素节点
  • document.forms:获取页面中所有的 form 元素节点
  • document.documentElement:获取根元素

在 JS 中,获取到的一大坨东西基本都不是真的数组,而是伪数组,其原因有很多方面,例如性能考虑,功能需求的考虑,甚至还有一些历史遗留问题,这里不详细展开。

上面这些是很古老的方式,但是 document.body 和 document.documentElement 实际上还是比较有用的,但其他的就没什么用了,我们有更加强大的获取方式。

我们可以通过以下方法获取元素

  • document.getElementById():通过 id 属性获取元素,由于 ID 是唯一的,所以这种方式获取到的一定是唯一的一个 DOM 元素。这个方式可以锁定唯一一个元素,所以执行效率是最高的。
  • document.getElementsByTagName():通过元素名称获取元素,得到一个类数组
  • document.getElementsByClassName():通过元素的 class 属性获取元素,得到一个类数组(IE 9 以下无效)
  • document.getElementsByName():通过元素的 name 属性值获取元素
  • document.querySelector():通过元素的 CSS 选择器获取元素,这个方法只会获取第一个匹配到的元素(IE 8 以下无效)
  • document.querySelectorAll():同样通过元素的 CSS 选择器获取元素,可以获取所有匹配到的元素

注:在所有的得到类数组的方法中,除了 querySelectorAll 以外,其他的方法都是实时更新的。
举个例子,假设我通过 getElementsByTagName 得到了 5 个 a 元素,保存在一个变量中,如果我现在在页面上将 a 元素删掉一个,那么这个变量里面的类数组也会跟着减少一个,也就是说除了 querySelectorAll 以外,其他的方法得到的类数组都会根据网页自动变化。

这里有一个细节,如果一个元素书写了 ID 属性,那么这个属性会自动成为 window 对象的属性,可以直接在全局通过 id 属性拿到这个元素,这是早期浏览器为了方便开发者快速获取某个 dom 元素而做出的设计,但是在现在看来这种方式存在非常多的问题,例如命名冲突。

其中 document.getElementsByTagName(),document.getElementsByClassName(),document.querySelector(), document.querySelectorAll() 这四个元素可以作为其他元素节点的方法使用,假设 elem 是一个元素,则可以使用 elem.querySelectorAll() 来在 elem 元素内部进行查找。

除了这样直接获取以外,还可以间接获取到一个元素,也就是可以通过 DOM 节点之间的关系来获取节点,比如我要获取某个元素的所有子元素,这些其实都可以实现,这里一一列举,注意,这里是节点操作,而不是元素操作,我们可以获取到所有节点,包括文本节点这些东西,下面的 Node 为节点对象

  • Node.parentNode:获取该节点的父节点(一定是元素节点)
  • Node.nextSibling:获取下一个兄弟节点
  • Node.previousSibling:获取上一个兄弟节点
  • Node.childNodes:获取所有孩子节点,返回一个伪数组
  • Node.firstChild:获取第一个子节点
  • Node.lastChild:获取最后一个子节点
  • Node.attributes:获取某个元素节点的属性节点,返回一个类数组

节点关系图

这里获取的都是节点,并不是元素,也就是说上面的方式可以获取到文本,注释这些东西,我获取这些完全就没用对吧,所以这种方式其实用的很少,由于我们执行的操作大多数是对元素节点进行操作,所以 WEBAPI 有提供了一些专门用于获取元素节点的方式。

  • Element.previousElementSibling:获取上一个元素兄弟
  • Element.nextElementSibling:获取下一个元素兄弟
  • Element.parentElement:获取父元素
  • Element.children:获取子元素
  • Element.firstElementChild :获取第一个子元素
  • Element.lastElementChild:获取最后一个子元素

这些获取到的都是元素节点,所以这些才是我们真正常用的方法。

注:不管是 Element.children 还是 Node.childNodes,都是实时更新的。

对于一个节点,包括非元素节点,作为一个对象,上面都有很多属性可以供我们使用

  • Node.nodeName:节点名称(元素节点得到的节点名称都是大写)
  • Node.nodeValue:节点的值
  • Node.nodeType:获取节点类型,返回一个数字 节点类型

注意,本文的重点应该是元素的获取操作,不应把重点放在节点的获取和操作上。

以笔记为镜,可以知得失