如何遍历整个DOM树

原文链接:[如何遍历整个DOM树(外网原文链接)](https://chrisdeo.github.io/2019/07/20/%E5%A6%82%E4%BD%95%E9%81%8D%E5%8E%86%E6%95%B4%E4%B8%AADOM%E6%A0%91/)

作为前端开发工程师,我们大部分工作内容其实还是围绕着DOM在进行Javascript的编写;为了获取对应的DOM节点,我们通常会使用选择器来直接获取对应的元素。但如果让我们访问一整棵DOM树,针对某个环节进行操作呢?这就需要我们对DOM的基本属性以及树的数据结构有比较深刻的认识了。

nodeType:

在开始遍历操作前,我们先要知道DOM元素nodeType这个属性的意义,它以数字值返回指定节点的节点类型,我们这里只例举常见的几种:
nodeType1时,表明该节点为元素节点,如body、div等;
nodeType2时,表明该节点为属性节点,啥是属性节点呢,其实就是src、target这种,只不过我们平常都是以属性来访问它们而不是将其当属性节点提取出;
nodeType3时,表明该节点为文本节点。


DFS:

在知道以上的基本要素后,我们就可以用深度遍历(DFS)的方式开始递归遍历DOM树:

function traverseByDFS(root){if(!root) return;if(root.nodeType === 1){let len = root.children.length;console.log(root.nodeName + " ." + root.className);for(let i=0;i<len;i++){traverseByDFS(root.children[i]);}}
}

例如以下这段代码:

<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div class="root"><div class="container"><section class="sidebar"><ul class="menu"></ul></section><section class="main"><article class="post"></article><p class="copyright"></p></section></div></div>
</body><script>function traverseByDFS(root){if(!root) return;if(root.nodeType === 1){let len = root.children.length;console.log(root.nodeName + " ." + root.className);for(let i=0;i<len;i++){traverseByDFS(root.children[i]);}}}traverseByDFS(document.getElementsByClassName('root')[0]);
</script></html>

以上代码的运行结果为:
在这里插入图片描述


BFS:

对于DOM树的广度遍历来说,关键是如何保存同层节点的访问顺序以便之后继续对他们的子节点进行遍历,而DOM树本身就是构造完整的,我们直接访问对应节点属性就可以拿到相邻元素、祖先元素以及后代元素的值。所以只需要结合队列的特性就可以保存顺序再通过递归访问即可遍历所有元素。

在这里插入图片描述
BFS代码如下:

function traverseByBFS(root){if(!root) return;let queue = [];let rootFirstKid = root.firstElementChild;if (rootFirstKid) {queue.unshift(rootFirstKid);console.log(queue[0].nodeName + ' .' + queue[0].className);while (rootFirstKid.nextElementSibling) {queue.unshift(rootFirstKid.nextElementSibling);console.log(queue[0].nodeName + ' .' + queue[0].className);rootFirstKid = rootFirstKid.nextElementSibling;}while (queue.length) {let whoIsOut = queue.pop(); // 取队列的第一个,其实是在数组的尾部traverseByBFS(whoIsOut);}}
}

例如以下这段代码:

<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div class="root"><div class="container"><section class="sidebar"><ul class="menu"></ul></section><section class="main"><article class="post"></article><p class="copyright"></p></section></div></div>
</body><script>function traverseByBFS(root){if(!root) return;let queue = [];let rootFirstKid = root.firstElementChild;if (rootFirstKid) {queue.unshift(rootFirstKid);console.log(queue[0].nodeName + ' .' + queue[0].className);while (rootFirstKid.nextElementSibling) {queue.unshift(rootFirstKid.nextElementSibling);console.log(queue[0].nodeName + ' .' + queue[0].className);rootFirstKid = rootFirstKid.nextElementSibling;}while (queue.length) {let whoIsOut = queue.pop(); // 取队列的第一个,其实是在数组的尾部traverseByBFS(whoIsOut);}}}traverseByBFS(document.getElementsByClassName('root')[0]);
</script></html>

以上代码的运行结果为:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/289107.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL把统计结果作为条件进行查询

今天在社区看到一个问题如何返回 统计数值&#xff0c;比较简单&#xff0c;分享一下写法&#xff1a; --测试数据 if not object_id(NTempdb..#T) is nulldrop table #T Go Create table #T([name] nvarchar(21),[year] nvarchar(21),[time] nvarchar(22)) Insert #T select …

手写SpringBoot(二)之动态切换Servlet容器

系列文章目录 手写SpringBoot&#xff08;一&#xff09;之简易版SpringBoot 手写SpringBoot&#xff08;二&#xff09;之动态切换Servlet容器 手写SpringBoot&#xff08;二&#xff09;之动态切换Servlet容器 文章目录 系列文章目录手写SpringBoot&#xff08;二&#xff…

KubeSphere简单介绍及安装使用

KubeSphere 概述 官网地址&#xff1a;https://kubesphere.io/zh/ 什么是 kubesphere KubeSphere 是一个开源的多云容器管理平台&#xff0c;旨在简化企业级 k8s 集群的部署、管理和运维。它提供了一个可视化的管理界面&#xff0c;帮助用户更轻松地管理和监控 k8s 集群&…

访问者模式(数据与行为解耦)

目录 前言 UML plantuml 类图 实战代码 SimpleFileVisitor FileVisitor 接口 删除指定文件夹 模板 IVisitor IVisitable Client 前言 一个类由成员变量和方法组成&#xff0c;成员变量即是类的数据结构&#xff0c;方法则是类的行为。 如果一个类的数据结构稳定&am…

超声波清洗机家用的哪家好?眼镜清洗器推荐!一分钟选购洗眼镜机

相信大家都知道&#xff0c;眼镜脏的话可以使用超声波清洗机清洁&#xff01;因为超声波清洗机能够通过振频的原理&#xff0c;对眼镜的污垢进行清洗。有的朋友会问&#xff0c;我手洗不可以吗&#xff1f;手洗当然可以&#xff0c;但是手洗对于镜片的清洗有作用&#xff0c;但…

【C语言】 gets()puts()fgets()fputs()字符串输入输出函数的用法

文章目录 C语言中的字符串输入输出函数&#xff1a;gets、puts、fgets与fputsgets函数puts函数fgets函数fputs函数 C语言中的字符串输入输出函数知识点总结结语 C语言中的字符串输入输出函数&#xff1a;gets、puts、fgets与fputs 在C语言中&#xff0c;处理字符串的输入和输出…

Java关键字之 assert

语法 assert关键字语法有两种用法&#xff1a; 1、assert <boolean表达式> 如果<boolean表达式>为true&#xff0c;则程序继续执行。 如果为false&#xff0c;则程序抛出AssertionError&#xff0c;并终止执行。 2、assert <boolean表达式> : <错误信…

翔云身份证实名认证接口-PHP调用方法

网络平台集成实名认证接口&#xff0c;是顺应当下网络实名制规定&#xff0c;有效规避法律风险。互联网平台若没有实名认证功能&#xff0c;那么便无法保证网民用户身份的真实性&#xff0c;很有可能被虚假用户攻击&#xff0c;特别是在当网络平台产生垃圾信息乃至是违法信息时…

必示科技携手云杉网络发布“智能可观测性联合解决方案”

近日&#xff0c;必示科技与云杉网络携手发布“智能可观测性联合解决方案”&#xff0c;整体方案融合云杉网络DeepFlow产品在可观测性领域、必示科技AIOps产品在运维数据分析领域的深厚技术积淀&#xff0c;完整实现IT系统高质量、高性能、全栈的可观测数据采集、智能监控和智能…

Go —— defer

defer defer 语句用于延迟函数的调用&#xff0c;常用于关闭文件描述符、释放锁等资源释放场景。但 defer 关键字只能作用于函数或函数调用。 defer func(){ // 函数fmt.Print("Hello&#xff0c;World!") }()defer fmt.Print("Hello&#xff0c;World!&…

第十三届国际纯数学与应用数学会议(ICPAM 2024)即将召开!

第十三届国际纯数学与应用数学会议将于2024年7月17日至20日在克罗地亚萨格勒布召开。ICPAM是一项连续成功举办十二年的年度会议&#xff0c;其汇集了纯数学和应用数学领域的教授、研究人员、学者和学生&#xff0c;为跨行业交流&#xff0c;经验分享&#xff0c;学术界合作以及…

ArcGIS Pro横向水平图例

终于知道ArcGIS Pro怎么调横向图例了&#xff01; 简单的像0一样 旋转&#xff0c;左转右转随便转 然后调整图例项间距就可以了&#xff0c;参数太多就随便试&#xff0c;总有一款适合你&#xff01; 要调整长度&#xff0c;就调整图例块的大小。完美&#xff01; 好不容易…

【C++】手撕哈希表的闭散列和开散列

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;手撕哈希表的闭散列和开散列 > 毒鸡汤&#xff1a;谁不是一边受伤&#xff0c;一边学会坚强。 > 专栏选自&#xff1a;C嘎嘎进阶 > 望小伙伴们…

对AOP的理解

目录 一、为何需要AOP&#xff1f;1、从实际需求出发2、现有的技术能解决吗&#xff1f;3、AOP可以解决 二、如何实现AOP&#xff1f;1、基本使用2、更推荐的做法2.1 “基本使用”存在的隐患2.2 最佳实践2.2.1 参考Transactional&#xff08;通过AOP实现事务管理&#xff09;2.…

SpringBoot国际化配置流程(超详细)

前言 最新第一次在做SpringBoot的国际化&#xff0c;网上搜了很多相关的资料&#xff0c;都是一些简单的使用例子&#xff0c;达不到在实际项目中使用的要求&#xff0c;因此本次将结合查询的资料以及自己的实践整理出SpringBoot配置国际化的流程。 SpringBoot国际化 "i…

用系统观念打造智慧公厕,引领智慧城市的发展

智慧公厕&#xff0c;作为智慧城市建设的一部分&#xff0c;具有重要意义。在高度发达的科技条件下&#xff0c;如何打造高质量的智慧公厕是一个值得思考的问题。本文将以智慧公厕源头实力厂家广州中期科技有限公司&#xff0c;大量精品案例项目现场实景实图实例&#xff0c;探…

Rust控制台输出跑马灯效果,实现刷新不换行,实现loading效果

要在 Rust 中实现控制台刷新而不换行&#xff0c;以实现类似 "loading" 状态的效果&#xff0c;你可以使用 \r&#xff08;回车符&#xff09;来覆盖上一行的内容。 use std::io::{self, Write}; use std::thread; use std::time::Duration;fn main() {let loading_…

浅模仿小米商城布局(有微调)

CSS文件 *{margin: 0;padding: 0;box-sizing: border-box; }div[class^"h"]{height: 40px; } div[class^"s"]{height: 100px; } .h1{width: 1528px;background-color: green; } .h11{background-color:rgb(8, 220, 8); } .h111{width: 683px;background-c…

动态内存操作函数使用过程中会遇见的问题

越界访问 首先我们上一个代码&#xff0c;看看这个的代码的问题 这个代码的问题显而易见 &#xff0c;就是在循环里面&#xff0c;产生了越界访问的问题&#xff0c;这里你开辟了10个整形空间&#xff0c;但是从0-10一共是11个整形空间。导致访问不合法的空间&#xff0c;从而…

卷积神经网络-卷积层

卷积神经网络-卷积层 1多层感知机&#xff08;MLP&#xff09;2卷积神经网络&#xff08;CNN&#xff09;3MLP和CNN关系与区别4仍然有人使用MLP的原因&#xff1a;5MLP的局限性&#xff1a;MLP的应用领域&#xff1a;总结&#xff1a;6全连接到卷积全连接层 vs 卷积层结构差异应…