我们在阅读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,实体引用节点(&quot
  • 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
  • 我们重新修改后的代码如下:
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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节点树和元素树--深度遍历的更多相关文章

  1. 006 DOM节点操作与元素的创建

    一:节点 1.节本基本概念 节点主要有标签,属性,文本[包括文字,空格,换行,回车]. 2.节点的属性 可以使用标签,元素点出来 可以使用标签,点出来 可以使用文本,点出来 nodeType:1--标 ...

  2. js学习总结:DOM节点二(dom基本操作)

    一.DOM继承树 DOM——Document Object Model DOM定义了表示修改文档所需要的方法.DOM对象即为宿主对象,由浏览器厂商定义,用来操作html和xml的一类厂商定义,也有人称 ...

  3. jQuery操作DOM节点的方法总结

    1.parent():获得当前匹配元素集合中每个元素的父元素,该方法只会向上一级对 DOM 树进行遍历 $('li.item-a').parent().css('background-color', ...

  4. js中的DOM节点

    文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法. DOM 将HTML文档呈现为带有元素.属性和文本的树结构(节点树). 把上面的代码拆分为Dom节 ...

  5. childNodes遍历DOM节点树

    childNodes遍历DOM节点树 var s = ""; function travel(space,node) { if(node.tagName){ s += space ...

  6. java遍历树(深度遍历和广度遍历

    java遍历树如现有以下一颗树:A     B          B1               B11          B2               B22     C          C ...

  7. 多级树的深度遍历与广度遍历(Java实现)

    目录 多级树的深度遍历与广度遍历 节点模型 深度优先遍历 广度优先遍历 多级树的深度遍历与广度遍历 深度优先遍历与广度优先遍历其实是属于图算法的一种,多级树可以看做是一种特殊的图,所以多级数的深/广遍 ...

  8. DOM 元素的循环遍历

    ​博客地址:https://ainyi.com/89​ 获取 DOM 元素的几种方式 get 方式: getElementById getElementsByTagName getElementsBy ...

  9. 深入理解DOM节点类型第五篇——元素节点Element

    × 目录 [1]特征 [2]子节点 [3]特性操作[4]attributes 前面的话 元素节点Element非常常用,是DOM文档树的主要节点:元素节点是html标签元素的DOM化结果.元素节点主要 ...

随机推荐

  1. jvm高级特性(4)(内存分配回收策略)

    JVM高级特性与实践(四):内存分配 与 回收策略 一. 内存分配 和 回收策略 1,对象内存分配的概念: 往大方向讲,它就是在堆上分配(但也可能经过JIT编译后被拆散为标量类型并间接地栈上分配), ...

  2. 奇怪的Java题:为什么1000 == 1000返回为False,而100 == 100会返回为True?

    如果你运行如下代码: 1 2 3 4 Integer a = 1000, b = 1000;  System.out.println(a == b);//1 Integer c = 100, d =  ...

  3. ORACLE----触发器,存储过程及JOB

    一.Oracle中创建自增的ID字段1.创建序列 create *sequence_name*  increment by 1 start with 1 maxvalue 999999999;2.创建 ...

  4. Python小白学习之路(三)—【数字功能】【字符串功能】

    数字(int)常见功能 在网络课上,老师把这些功能称为神奇的魔法,想要揭开魔法神奇的面纱,想要看看有什么招数,在Pycharm里敲击三个字母(int),按住Ctrl,将鼠标点在int上,这时鼠标会变成 ...

  5. Go语言学习笔记(2)——变量、常量

    1. 变量(变量由字母.数字和下划线组成,且不能以数字开头!)      1.1 第一种 var name type // 未赋值时使用默认值 name = value 1.2 第二种: 根据所赋的值 ...

  6. 【bzoj3224】【Tyvj 1728】 普通平衡树 树状数组

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入$x$数2. 删除$x$数(若有多个相同的数,因只删除一个)3. 查询$x$数的排名(若有多个相同的数,因输出最小 ...

  7. (转)MySQL日志管理

    MySQL 服务器上一共有六种日志:错误日志,查询日志,慢查询日志,二进制日志,事务日志,中继日志. 原文:https://segmentfault.com/a/1190000003072237 一 ...

  8. android动态权限获取

    android动态权限获取 Android6.0采用新的权限模型,只有在需要权限的时候,才告知用户是否授权,是在runtime时候授权,而不是在原来安装的时候 ,同时默认情况下每次在运行时打开页面时候 ...

  9. Mac 下安装node.js(转载)

    原文地址:http://blog.csdn.net/u011619283/article/details/52368759 Node.js 简介 Node.js 是一个用Chrome's V8 Jav ...

  10. 【Git】学习记录

    配置git git config --global user.name "用户名或者用户ID" git config --global user.email "邮箱&qu ...