第七章DOM 7.1 JavaScript DOM 介绍

199 阅读8分钟

7.1 DOM 介绍

DOM 是指文档对象模型(Document Object Model),是一种用于 HTML、XML 等文档的编程接口。DOM 以树形结构表示文档,允许开发者通过编程方式操作文档的内容、结构和样式。 在 JavaScript 中,DOM 是由浏览器提供的 API,它将 HTML 文档表示为一个树形结构,每个 HTML 元素都是树中的一个节点。通过 DOM,开发者可以通过 JavaScript 代码来获取、修改、添加或删除 HTML 元素,以及监听元素上的事件。 DOM 树的结构 在 JavaScript 中,DOM 树是用来表示 HTML 文档的树形结构。它由一个根节点(文档节点)和若干个子节点(元素节点、文本节点、注释节点等)组成。 DOM 树的结构可以用一个简单的示意图来表示: image

在这个示意图中,DOM 树的根节点是 document,它有一个子节点 html 元素,html 元素又有两个子节点 head 和 body 元素,head 元素包含一个子节点 title 元素,body 元素包含一个子节点 div 元素,div 元素又包含一个子节点 p 元素和一个文本节点。 以下是一个简单的 HTML 结构及其对应的 DOM 树:

<!DOCTYPE html>
<html>
  <head>
    <title>Example</title>
  </head>
  <body>
    <h1>Hello, World!</h1>
    <p>This is an example of a HTML document.</p>
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>
  </body>
</html>

对应的 DOM 树如下:

Document
├──<!DOCTYPE html>
└──html
├──head
│ └──title
│ └──"Example"
└──body
├──h1
│ └──"Hello, World!"
├──p
│ └──"This is an example of a HTML document."
└──ul
├──li
│ └──"Item 1"
├──li
│ └──"Item 2"
└──li
└──"Item 3"

在 DOM 树中,每个节点都是一个对象,有其自己的属性和方法,可以通过 JavaScript 代码来访问和操作。例如,可以使用以下代码来获取文档标题的内容:

var title = document.getElementsByTagName('title')[0];
console.log(title.innerHTML); // "Example"

这里使用 document.getElementsByTagName 方法获取<title>元素,然后使用 innerHTML 属性获取其内容。

DOM 节点类型

在 JavaScript 中,DOM 节点是指 HTML 文档中的每个元素节点在 JavaScript 中的表示。DOM 节点可以分为以下几种类型:

  1. 元素节点(Element):表示 HTML 文档中的标签,例如<div>、<p>、<ul>等。
  2. 文本节点(Text):表示 HTML 文档中的文本内容,例如<p>标签中的文本内容。
  3. 属性节点(Attribute):表示 HTML 文档中元素的属性,例如元素<img>的属性 src、alt 等。
  4. 注释节点(Comment):表示 HTML 文档中的注释,例如。
  5. 文档节点(Document):表示整个 HTML 文档,它是 DOM 树的根节点。
  6. 文档类型节点(DocumentType):表示 HTML 文档的文档类型,例如<!DOCTYPE html>
  7. 文档片段节点(DocumentFragment):表示一个空的文档片段,可以用来临时存储节点,以便在稍后将它们添加到文档中。

DOM 节点具有一些公共的属性和方法,例如获取节点的标签名、获取或设置节点的文本内容、获取或设置节点的属性等。通过 JavaScript 代码,我们可以使用 DOM API 来访问和操作 HTML 文档中的节点,实现对页面的动态更新和交互效果。

节点 nodeName 属性

节点的 nodeName 属性返回这个节点的名称,名称取决于节点的类型:

  • 元素节点:nodeName 属性返回元素的标签名(不含尖括号)。例如,对于一个<div>元素,nodeName 属性将返回字符串"DIV"。
  • 属性节点:nodeName 属性返回属性的名称。例如,对于一个 class 属性,nodeName 属性将返回字符串"class"。
  • 文本节点:nodeName 属性始终返回#text。例如,对于一个包含文本内容的<p>元素,它的第一个子节点将是一个文本节点,nodeName 属性将返回字符串"#text"。
  • 注释节点:nodeName 属性始终返回#comment。例如,对于一个注释节点,nodeName 属性将返回字符串"#comment"。
  • 文档节点: nodeName 属性始终返回字符串"#document"。文档节点是 DOM 树的根节点,它代表整个 HTML 或 XML 文档。
  • 文档片段节点:nodeName 属性同样返回字符串"#document-fragment"。文档片段节点是一个虚拟的节点,它可以用来创建一些 DOM 节点,然后将它们一次性添加到 DOM 树中,从而提高性能。
  • 文档类型节点:nodeName 属性返回文档类型的名称,如 HTML、SVG、XML 等等。文档类型节点表示文档的类型声明,它包含文档的 DTD(文档类型定义)信息,以及一些关于文档类型的其他信息。

下面是一个简单的例子,展示如何获取一个元素节点的属性节点的 nodeName 值:

<!DOCTYPE html>
<html>
  <head>
    <title>属性节点nodeName示例</title>
  </head>
  <body>
    <a href="https://www.example.com" target="_blank">点击这里</a>

    <script>
      var link = document.querySelector('a');
      var attribute = link.getAttributeNode('href');

      console.log('属性节点的nodeName: ' + attribute.nodeName); //href
    </script>
  </body>
</html>

节点 nodeType 属性

节点的 nodeType 属性用于获取节点的类型,它是一个整数值。节点类型和对应的常量如下:

  • 元素节点(element):1(Node.ELEMENT_NODE)
  • 属性节点(attribute):2(Node.ATTRIBUTE_NODE)
  • 文本节点(text):3(Node.TEXT_NODE)
  • 注释节点(comment):8(Node.COMMENT_NODE)
  • 文档节点(document):9(Node.DOCUMENT_NODE)
  • 文档类型节点(document type):10 (Node.DOCUMENT_TYPE_NODE)
  • 文档片段节点(document fragment):11(Node.DOCUMENT_FRAGMENT_NODE) 例如,在 JavaScript 中,可以使用 Node.ELEMENT_NODE 常量来代替数字 1 来表示元素节点的类型。这样做的好处在于,可以提高代码的可读性和可维护性。以下是一个例子:
<!DOCTYPE html>
<html>
  <head>
    <title>使用常量示例</title>
  </head>
  <body>
    <div id="myDiv">
      这是一个
      <div>元素。</div>
    </div>

    <script>
      var div = document.getElementById('myDiv');
      if (div.nodeType === Node.ELEMENT_NODE) {
        console.log('这是一个元素节点。');
      } else {
        console.log('这不是一个元素节点。');
      }
    </script>
  </body>
</html>

在这个例子中,我们首先使用 Node.ELEMENT_NODE 常量来代替数字 1,然后使用 if 语句来判断该节点是否为元素节点,并通过控制台输出相应的信息。在这个例子中,由于我们获取的是一个元素节点,所以 if 语句中的代码块将被执行,输出字符串"这是一个元素节点。"。

获取节点关系

JavasSript 提供方法可以由一个 DOM 节点或者这个节点相关的其他节点,常见的方法如下:

  1. parentNode:获取当前节点的父节点。
const childNode = document.getElementById('child');
const parentNode = childNode.parentNode;
  1. childNodes:获取当前节点的所有子节点。
const parentNode = document.getElementById('parent');
const childNodes = parentNode.childNodes;
  1. nextSibling 和 previousSibling:获取当前节点的前一个和后一个同级节点
const currentNode = document.getElementById('current');
const nextSibling = currentNode.nextSibling;
const previousSibling = currentNode.previousSibling;
  1. firstChild 和 lastChild:获取当前节点的第一个和最后一个子节点。
const parentNode = document.getElementById('parent');
const firstChild = parentNode.firstChild;
const lastChild = parentNode.lastChild;
  1. parentElement:获取当前节点的父元素节点,不同于 parentNode,它只会获取元素节点而不包括文本节点等其他节点。
const childNode = document.getElementById('child');
const parentElement = childNode.parentElement;
  1. children:获取当前节点的所有子元素节点。
const parentNode = document.getElementById('parent');
const children = parentNode.children;
  1. previousElementSibling 和 nextElementSibling:获取当前节点的前一个和后一个同级元素节点。
const currentNode = document.getElementById('current');
const previousElementSibling = currentNode.previousElementSibling;
const nextElementSibling = currentNode.nextElementSibling;

以下是一个综合使用以上这些方法的例子:

<!DOCTYPE html>
<html>
  <head>
    <title>使用常量示例</title>
  </head>
  <body>
    <div id="parent">
      <p>第一个段落</p>
      <p>第二个段落</p>
      <ul>
        <li>第一个列表项</li>
        <li>第二个列表项</li>
      </ul>
    </div>
    <script>
      const parentNode = document.getElementById('parent');
      // 获取父节点
      const parent = parentNode.parentNode;
      console.log(parent); // <body>...</body>

      // 获取所有子节点
      const childNodes = parentNode.childNodes;
      console.log(childNodes); // NodeList(7) [text, p, text, p, text, ul, text]

      // 获取第一个子节点
      const firstChild = parentNode.firstChild;
      console.log(firstChild); // #text

      // 获取最后一个子节点
      const lastChild = parentNode.lastChild;
      console.log(lastChild); // #text

      // 获取第一个元素子节点
      const firstElementChild = parentNode.firstElementChild;
      console.log(firstElementChild); // <p>第一个段落</p>

      // 获取最后一个元素子节点
      const lastElementChild = parentNode.lastElementChild;
      console.log(lastElementChild); // <ul>...</ul>

      // 获取所有元素子节点
      const children = parentNode.children;
      console.log(children); // HTMLCollection(3) [p, p, ul]

      // 获取当前节点的前一个同级节点
      const previousSibling = lastChild.previousSibling;
      console.log(previousSibling); // <ul>...</ul>

      // 获取当前节点的后一个同级节点
      const nextSibling = firstChild.nextSibling;
      console.log(nextSibling); // <p>第一个段落</p>

      // 获取当前元素节点的父元素节点
      const parentElement = firstChild.parentElement;
      console.log(parentElement); // <div id="parent">...</div>

      // 获取当前元素节点的前一个同级元素节点
      const previousElementSibling = lastElementChild.previousElementSibling;
      console.log(previousElementSibling); // <p>第二个段落</p>

      // 获取当前元素节点的后一个同级元素节点
      const nextElementSibling = firstElementChild.nextElementSibling;
      console.log(nextElementSibling); // <p>第二个段落</p>
    </script>
  </body>
</html>

可见,childNodes 返回的是一个 NodeList 对象,包含了当前节点的所有子节点,顺序是按照子节点在文档中的顺序排列的。文档中的顺序是指节点在 HTML 源代码中出现的顺序,而不是节点在 DOM 树中的顺序。 需要注意的是,childNodes 包含了所有类型的节点,包括文本节点、注释节点等,而不仅仅是元素节点。因此在使用时需要注意区分。 如果只需要获取元素节点,可以使用 children 属性,它返回的是一个 HTMLCollection 对象,只包含元素节点,且顺序也是按照子元素在文档中的顺序排列的。与 childNodes 不同,children 不包括文本节点、注释节点等其他类型的节点。 所以在例子中,childNodes 获取到了 7 个字节点,其中的 text 节点都是元素节点之间的文本节点,该文本节点的截图如下:

获取元素节点的方法更常用。

document 对象

document 是一个全局对象,表示当前浏览器窗口中加载的 HTML 文档。在 JavaScript 中,全局对象指的是可以在任何地方都能够访问到的对象,在浏览器环境中,当一个 HTML 文档被加载到浏览器中时,浏览器会自动创建一个 document 对象,它代表了当前文档,并且可以通过全局变量 document 来访问。 document 对象提供了一系列方法和属性,可以用来获取、创建、修改、删除文档中的元素和内容,比如获取元素对象、修改元素内容、修改元素样式等。一些常用的 document 对象方法和属性包括:

  1. document.getElementById(id):获取 ID 为 id 的元素对象。
  2. document.getElementsByTagName(tagName):获取标签名为 tagName 的所有元素对象。
  3. document.createElement(tagName):创建一个指定标签名的元素对象。
  4. document.createTextNode(text):创建一个包含指定文本的文本节点对象。
  5. document.body:获取元素对象。
  6. document.head:获取元素对象。
  7. document.title:获取或设置文档的标题。
  8. document.URL:获取文档的 URL。
  9. document.write(content):向文档中写入 HTML 内容。
  10. document.cookie:获取或设置文档的 cookie。