上一节我们学习了JS中DOM的一些基础操作,本节我们开始学习DOM的遍历。我们都知道,DOM的本质其实是一棵树,因此,当我们获取某个元素时,我们可以根据DOM方法来获取该元素上一级的所有节点或下一级的所有节点,就像是树的遍历一样,通过一个元素拿到相关元素。下面我们通过表格展示一些DOM树遍历的内置属性和方法:

函数/属性功能
parentNode返回当前节点的父节点
parentElement返回当前节点的父元素节点
childNodes返回当前节点的所有子节点的集合
children返回当前节点的所有元素子节点的集合
firstChild返回当前节点的第一个子节点
firstElementChild返回当前节点的第一个元素子节点
lastChild返回当前节点的最后一个子节点
lastElementChild返回当前节点的最后一个元素子节点
nextSibling返回当前节点的下一个兄弟节点
nextElementSibling返回当前节点的下一个元素兄弟节点
previousSibling返回当前节点的上一个兄弟节点
previousElementSibling返回当前节点的上一个元素兄弟节点
querySelector()返回文档中匹配指定CSS选择器的第一个元素
querySelectorAll()返回文档中匹配指定CSS选择器的所有元素
getElementById()返回对拥有指定id的第一个对象的引用
getElementsByClassName()返回文档中所有指定类名的元素集合
getElementsByTagName()返回带有指定标签名的对象集合
closest()返回当前元素中与选择器匹配的最接近的祖先元素

比如我们现在有一个简单的页面,包括header、main和footer:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dotcpp编程</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: sans-serif;
            line-height: 1.6;
        }
        
        .container {
            width: 90%;
            max-width: 1200px;
            margin: 0 auto;
            padding: 1rem 0;
        }
        
        /* 导航栏样式 */
        header {
            border-bottom: 1px solid #ccc;
            padding: 1rem 0;
        }
        
        nav {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        
        .logo {
            font-size: 1.2rem;
            font-weight: bold;
        }
        
        .nav-links {
            display: flex;
            list-style: none;
        }
        
        .nav-links li {
            margin-left: 1.5rem;
        }
        
        .nav-links a {
            text-decoration: none;
            color: #333;
        }
        
        /* 主要内容区域样式 */
        .grid-container {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
            gap: 1rem;
            margin-top: 1.5rem;
        }
        
        .card {
            border: 1px solid #ccc;
            padding: 1rem;
        }
        
        .card h3 {
            margin-bottom: 0.5rem;
        }
        
        /* 页脚样式 */
        footer {
            border-top: 1px solid #ccc;
            padding: 1rem 0;
            margin-top: 2rem;
        }
        
        .footer-content {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        
        .footer-links {
            display: flex;
            list-style: none;
        }
        
        .footer-links li {
            margin-left: 1rem;
        }
        
        .footer-links a {
            text-decoration: none;
            color: #333;
        }
    </style>
</head>
<body>
    <!-- 导航栏 -->
    <header>
        <div class="container">
            <nav>
                <div class="logo">Dotcpp编程</div>
                <ul class="nav-links">
                    <li><a href="#">首页</a></li>
                    <li><a href="#">服务</a></li>
                    <li><a href="#">产品</a></li>
                    <li><a href="#">关于我们</a></li>
                    <li><a href="#">联系我们</a></li>
                </ul>
            </nav>
        </div>
    </header>
    <!-- 主要内容区域 -->
    <main>
        <div class="container">
            <h1>DOM遍历</h1>
           
            <div class="grid-container">
                <div class="card">
                    <h3>服务一</h3>
                    <p>这里是服务一的简要描述。</p>
                </div>
               
                <div class="card">
                    <h3>服务二</h3>
                    <p>这里是服务二的简要描述。</p>
                </div>
               
                <div class="card">
                    <h3>服务三</h3>
                    <p>这里是服务三的简要描述。</p>
                </div>
               
                <div class="card">
                    <h3>服务四</h3>
                    <p>这里是服务四的简要描述。</p>
                </div>
               
                <div class="card">
                    <h3>服务五</h3>
                    <p>这里是服务五的简要描述。</p>
                </div>
               
                <div class="card">
                    <h3>服务六</h3>
                    <p>这里是服务六的简要描述。</p>
                </div>
            </div>
        </div>
    </main>
    <!-- 页脚 -->
    <footer>
        <div class="container">
            <div class="footer-content">
                <div class="copyright">
                    &copy; 2025@Dotcpp编程
                </div>
                <ul class="footer-links">
                    <li><a href="#">隐私政策</a></li>
                    <li><a href="#">使用条款</a></li>
                    <li><a href="#">网站地图</a></li>
                </ul>
            </div>
        </div>
    </footer>
    <script></script>
</body>

</html>

该页面的结构如下:

html 
├── head 
│   ├── meta 
│   ├── meta
│   ├── title
│   └── style 
└── body 
    ├── header 
    │   └── div
    │       └── nav 
    │           ├── div 
    │           └── ul 
    │               ├── li 
    │               │   └── a 
    │               ├── li 
    │               │   └── a 
    │               ├── li 
    │               │   └── a 
    │               ├── li 
    │               │   └── a 
    │               └── li 
    │                   └── a 
    ├── main 
    │   └── div 
    │       ├── h1 
    │       └── div 
    │           ├── div 
    │           │   ├── h3 
    │           │   └── p 
    │           ├── div 
    │           │   ├── h3 
    │           │   └── p 
    │           ├── div 
    │           │   ├── h3 
    │           │   └── p 
    │           ├── div 
    │           │   ├── h3 
    │           │   └── p
    │           ├── div 
    │           │   ├── h3 
    │           │   └── p 
    │           └── div 
    │               ├── h3 
    │               └── p 
    ├── footer
    │   └── div 
    │       └── div 
    │           ├── div 
    │           └── ul 
    │               ├── li 
    │               │   └── a 
    │               ├── li
    │               │   └── a 
    │               └── li 
    │                   └── a 
    └── script

具体遍历操作:

关于父子节点和父子元素之间的区别:节点包含的范围更大,注释、文本或者是空行、缩进都算是一个节点;而元素值得是HTML里内置的默认元素或是自定义元素。

1. 父子节点相互访问:对于body,文本节点(header前的换行和缩进)、<!-- 导航栏 -->···文本节点 (body结束前的换行和缩进)、<script>是它的子节点,它们可以相互访问:

  /*父子节点相互访问*/
  const father = document.querySelector('body')//取body标签
  const son1=document.querySelector('header')//取header
  const son2=document.querySelector('main')//取main
  const son3=document.querySelector('footer')//取footer
/* 向下访问*/
const arrF=father.childNodes
console.log(arrF[0]);// 文本节点 (header前的换行和缩进)
console.log(arrF[1]);// 注释节点 <!-- 导航栏 -->
console.log(arrF[2]);// 文本节点 (header后的换行和缩进)
console.log(arrF[3]);// header元素
console.log(arrF[4]);// 文本节点 (main前的换行和缩进)
console.log(arrF[5]);// 注释节点 <!-- 主要内容区域 -->
console.log(arrF[6]);// 文本节点 (main后的换行和缩进)
console.log(arrF[7]);// main元素
console.log(arrF[8]);// 文本节点 (footer前的换行和缩进)
console.log(arrF[9]);// 注释节点 <!-- 页脚 -->
console.log(arrF[10]);// 文本节点 (footer后的换行和缩进)
console.log(arrF[11]);// footer元素
console.log(arrF[12]);// 文本节点 (body结束前的换行和缩进)

/* 向上访问(由于非元素节点不好获取,这里就不具体展示了) */
console.log(son1.parentNode);//body
console.log(son2.parentNode);//body
console.log(son3.parentNode);//body

2.父子元素相互访问:同节点访问方式一样,只不过元素的话相比节点约束性大。对于body,它的子元素是header、main和footer。它们也可以相互访问:

/* 父子元素相互访问 */
  const father = document.querySelector('body')//取body标签
  const son1=document.querySelector('header')//取header
  const son2=document.querySelector('main')//取main
  const son3=document.querySelector('footer')//取footer
/* 向下访问*/
const arrF=father.children
console.log(arrF.length);

console.log(arrF[0]);// header元素
console.log(arrF[1]);// main元素
console.log(arrF[2]);// footer元素
console.log(arrF[3]);// <scripe>
/* 向上访问 */
console.log(son1.parentNode);//body
console.log(son2.parentNode);//body
console.log(son3.parentNode);//body

3. 首尾节点、元素的访问:需要注意的是,该获取方式针对的是获取元素的下一级的范围,并非同级。比如body的下一级,然后由该元素进行首尾节点、元素的访问:

/* 首尾元素、节点访问 */
  const father = document.querySelector('body')//取body标签
  console.log(father.firstElementChild);//首元素-header
  console.log(father.firstChild);//首节点-文本节点 (header前的换行和缩进)
  console.log(father.lastElementChild);//尾元素-<script>
  console.log(father.lastChild);//尾节点-<script>

4. 兄弟节点元素的访问:同级元素,而非下一级元素。比如我们可以通过main来获取前后元素和节点:

/*兄弟元素前后节点、元素访问*/
const son2 = document.querySelector('main') // 取main
console.log(son2.previousSibling);        // 前一个兄弟节点 (文本节点)
console.log(son2.nextSibling);            // 后一个兄弟节点 (文本节点)
console.log(son2.previousElementSibling); // 前一个兄弟元素 (header)
console.log(son2.nextElementSibling);     // 后一个兄弟元素 (footer)

总结:通过DOM树的遍历,我们可以灵活地获取元素,进而调整页面布局和内容。

点赞(185)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)