DOM节点树和元素树--深度遍历
我们在阅读JS高级程序设计的时候,提到了节点树的概念。比如说:
elem.parentNode---找elem的父节点;
elem.childNodes---找elem的所有的直接子节点;
elem.nextSibling---找elem的下一个同辈节点‘;
elem.previousSibling---找elem的上一个同辈节点
因为childNodes包含看不见的空格文本,还有注释等内容,所以使用起来不是太方便。
因此,JS又重新引入了元素树的概念。这个的话,在我们实际应用中,用的比较普遍。
元素树:仅仅包含元素节点的树结构,不是一颗新树,尽是节点数的子集;
elem.parentElement 找节点的父元素;
elem.children返回节点的所有子元素;
elem.firstElementChild 第一个直接子元素;
elem.lastElementChild 最后一个直接字元素;
elem.previousElementSibling 找elem的前一个兄弟元素;
elem.nextElementSibling 找elem的下个兄弟元素;
在这里,我们介绍一个笔试题:
遍历一个指定父节点下的所有后代节点,这里需要明确一点,就是所有的后代节点都需要遍历到:

1 <script type='text/javascript'>
2 function getChildren(parent){
//如果当前父节点不是文本节点,就输出标签名,否则输出文本内容
3 console.log(parent.nodeType!=3?parent.nodeName:parent.nodeValue);
//获得父节点的所有直接子节点
4 var children = parent.childNodes;
//遍历children中每个节点
5 for(var i =0,len =children.length;i<len;i++){
//Step2: 对当前子节点调用getChildren
6 getChildren(children[i]);//这里使用递归的调用方法;
7 //console.log(children[i].nodeType !=3?children[i].nodeName:children[i].nodeValue);
8 }
9 }
10 getChildren(document.body);
11 </script>

这里我们需要知道一个算法-----深度优先遍历:当同时有兄弟节点和子节点的时候,总是优先遍历子节点。
上面代码的遍历顺序,就是优先遍历子节点。
我们在高性能JS这本书学到过,就是递归的运行效率没有迭代的运行效率高,所以,我们优化的话,一般都需要把递归的循环优化成迭代的循环。
上面的例子如何修改呢,这里我们要提到一个新的概念,那就是:
NodeIterator 对象,可以对 DOM 树进行深度优先的搜索。
创建 NodeIterator 对象,需要使用 document 对象的 createNodeIterator() 方法,该方法接收四个参数:
- root,搜索开始的节点
- whatToShow,一个数值代码,表示哪些节点需要搜索
- filter,NodeFilter 对象,决定忽略哪些节点
- entityReferenceExpansion,布尔值,表示是否需要扩展实体引用
whatToShow 参数:
- NodeFilter.SHOW_ALL,显示所有节点
- NodeFilter.SHOW_ELEMENT,元素节点
- NodeFilter.SHOW_ATTRIBUTE,属性节点
- NodeFilter.SHOW_TEXT,文本节点
- NodeFilter.SHOW_CDATA_SECTION,
![CDATA]节点 - NodeFilter.SHOW_ENTITY_REFERENCE,实体引用节点(
") - NodeFilter.SHOW_ENTITY,实体元素节点(
<!ENTITY foo "foo">) - NodeFilter.SHOW_PROCESSING_INSTRUCTION,PI 节点
- NodeFilter.SHOW_COMMENT,XML 注释节点
- NodeFilter.SHOW_DOCUMENT,文档顶层节点
- NodeFilter.SHOW_DOCUMENT_TYPE,DTD 节点
- NodeFilter.SHOW_DOCUMENT_FRAGMNT
- NodeFilter.SHOW_NOTATION
- 我们重新修改后的代码如下:
- 1234567891011121314
function getChildren(parent){//获取NodeIterator对象var t = document.createNodeIterator(parent,NodeFilter.SHOW_ALL,null,false);//循环遍历对象的下一个节点;var currNode=null;while((currNode=t.nextNode())!=null){//节点不为空,就一直循环遍历下去;直到为null,才中断循环;console.log(node.nodeType!=3?node.nodeName:node.nodeValue)}}getChildren(document.body);
DOM节点树和元素树--深度遍历的更多相关文章
- 006 DOM节点操作与元素的创建
一:节点 1.节本基本概念 节点主要有标签,属性,文本[包括文字,空格,换行,回车]. 2.节点的属性 可以使用标签,元素点出来 可以使用标签,点出来 可以使用文本,点出来 nodeType:1--标 ...
- js学习总结:DOM节点二(dom基本操作)
一.DOM继承树 DOM——Document Object Model DOM定义了表示修改文档所需要的方法.DOM对象即为宿主对象,由浏览器厂商定义,用来操作html和xml的一类厂商定义,也有人称 ...
- jQuery操作DOM节点的方法总结
1.parent():获得当前匹配元素集合中每个元素的父元素,该方法只会向上一级对 DOM 树进行遍历 $('li.item-a').parent().css('background-color', ...
- js中的DOM节点
文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法. DOM 将HTML文档呈现为带有元素.属性和文本的树结构(节点树). 把上面的代码拆分为Dom节 ...
- childNodes遍历DOM节点树
childNodes遍历DOM节点树 var s = ""; function travel(space,node) { if(node.tagName){ s += space ...
- java遍历树(深度遍历和广度遍历
java遍历树如现有以下一颗树:A B B1 B11 B2 B22 C C ...
- 多级树的深度遍历与广度遍历(Java实现)
目录 多级树的深度遍历与广度遍历 节点模型 深度优先遍历 广度优先遍历 多级树的深度遍历与广度遍历 深度优先遍历与广度优先遍历其实是属于图算法的一种,多级树可以看做是一种特殊的图,所以多级数的深/广遍 ...
- DOM 元素的循环遍历
博客地址:https://ainyi.com/89 获取 DOM 元素的几种方式 get 方式: getElementById getElementsByTagName getElementsBy ...
- 深入理解DOM节点类型第五篇——元素节点Element
× 目录 [1]特征 [2]子节点 [3]特性操作[4]attributes 前面的话 元素节点Element非常常用,是DOM文档树的主要节点:元素节点是html标签元素的DOM化结果.元素节点主要 ...
随机推荐
- nginx请求频率限制模块ngx_http_limit_req_module
模块: ngx_http_limit_req_module 作用: 限制客户端请求频率,防止恶意攻击 配置示例: http { limit_req_zone $binary_remote_addr z ...
- java程序连接hive数据库遇到的问题
今天,打算学习一下用hadoop做后台,搭建一个网站,首先第一步便是在本机的eclipse中连接到虚拟机上的hive中,原本以为很简单,但是过程很是艰难.特意做总结 首先hive的版本问题就是一个很大 ...
- javascript数据基本类型和引用类型区别详解
JavaScript基本数据类型: js基本数据类型包括:undefined,null,number,boolean,string.基本数据类型是按值访问的,就是说我们可以操作保存在变量中的实际的值. ...
- js with 语句的用法
with 语句 为语句设定默认对象. with (object) statements 参数 object 新的默认对象. statements 一个或多个语句,object 是该语句的默认对象 ...
- Catalina.createDigester方法详细理解
这个方法主要设置(这个方法很重要,贵在理解,虽然还没学过设计模式..) 1.遇到<server>标签时创建StandardServer实例 设置StandardServer类内部的相关 ...
- 电信固定ip宽带80与8080端口踩坑
本文只是作为记录,避免后面遇到此类问题耗费时间. 实际情况:公司有个固定电信宽带是固定IP的,想把固定IP映射到测试环境ip,实现可以公网通过固定ip访问,内网通过局域网ip访问. 测试环境服务是占用 ...
- 忽略“Signal: SIGSEGV (Segmentation fault)”
1. touch ~/.gdbinit 2. 在.gdbinit文件中添加“handle SIGSEGV nostop noprint pass”
- springboot-10-前端页面整合, thymeleaf, freemarker, jsp 模板使用
springboot 中不建议使用jsp作为页面展示, 怎么使用可以看: http://412887952-qq-com.iteye.com/blog/2292471 关于什么是thymeleaf, ...
- C#中通过Lambda表达式为委托传入更多的参数
如: DispatcherTimer dispatcherTimer = new DispatcherTimer(); dispatcherTimer.Tick += (o, e) => { d ...
- 解决Code First因_migrationHistory表与代码不一致的问题
我们在测试环境多人开发时,由于会存在多个测试.开发环境,但是大家共用一个数据库. 这时候会碰到一个问题,一旦有某个人通过Migration更新了数据库,其他环境在首次查询数据库的时候都会收到Dbcon ...