javascript先序遍历DOM树的方法


Posted in Javascript onFebruary 27, 2016

DOM树由文档中的所有节点(元素节点、文本节点、注释节点等)所构成的一个树结构,DOM树的解析和构建是浏览器要实现的关键功能。既然DOM树是一个树结构,那么我们就可以使用遍历树结构的相关方法来对DOM树进行遍历,同时DOM2中的"Traversal"模块又提供了两种新的类型,从而可以很方便地实现DOM树的先序遍历。

注:本文中的5种方法都是对DOM的先序遍历方法(深度优先遍历),并且只关注Element类型。

1. 使用DOM1中的基础接口,递归遍历DOM树

DOM1中为基础类型Node提供了一些api,通过这些api可以完成一些基础的DOM操作。使用递归遍历DOM树的代码比较简单,核心思想就是先处理当前节点,然后再从左到右递归遍历子节点,代码如下:

/**
  * 使用递归的方式先序遍历DOM树
  * @param node 根节点
  */
 function traversal(node){
   //对node的处理
   if(node && node.nodeType === 1){
     console.log(node.tagName);
   }
   var i = 0, childNodes = node.childNodes,item;
   for(; i < childNodes.length ; i++){
     item = childNodes[i];
     if(item.nodeType === 1){
       //递归先序遍历子节点
       traversal(item);
     }
   }
 }

2. 使用DOM1的基础接口,迭代遍历DOM树

与第1种方法不同,这一次使用迭代的方法遍历DOM树。使用迭代遍历DOM树相对复杂一些,关键点在于使用一个栈来维护节点的访问路径,当处理完当前节点时,先把该节点的第一个Element子节点作为下一次循环的根节点,并且按照从右到左的顺序,将当前节点的其他子元素节点压入栈中。如果当前节点没有一个Element子节点,则从栈中弹出一个Element节点作为下一次循环的根节点,直到取不到根节点为止。代码如下:

/**
 * 使用迭代的方式先序遍历DOM树
 * @param node 根节点
 */
function traversalIteration(node){
  var array = [], i = 0,k = 0,elementCount = 0, len = 0, childNodes,item;
  while(node != null){
    console.log(node.tagName);
    childNodes = node.childNodes;
    len = node.childNodes.length;
    elementCount = 0;
    if(len > 0){
      for(i = 0; i < len; i++){
        item = childNodes[i];
        if(item.nodeType === 1){
          elementCount++;
          node = item;
          break;
        }
      }
      for(k = len -1 ; k > i; k--){
        item = childNodes[k];
        if(item.nodeType == 1){
          elementCount++;
          array.push(item);
        }
      }
      if(elementCount < 1){
        node = array.pop();
      }
    }else{
      node = array.pop();
    }
  }
}

3. 使用DOM扩展的Element Traversal API,递归遍历DOM树

DOMElement Traversal API提供了几个方便DOM遍历的接口,从而可以更加方便地取得一个节点的Element子节点。在《DOM扩展:DOM API的进一步增强[总结篇-上]》的第2节介绍了DOM扩展的Element Traversal API。代码如下:

/**
 * 使用DOM扩展的Traversal API提供的新的接口先序遍历DOM树
 * @param node 根节点
 */
function traversalUsingTraversalAPI(node){
  if(node && node.nodeType === 1){
    console.log(node.tagName);
  }
  var i = 0,len = node.childElementCount, child = node.firstElementChild;
  for(; i < len ; i++){
    traversalUsingTraversalAPI(child);
    child = child.nextElementSibling;
  }
}

4. 使用NodeIterator

DOM2的"Traversal"模块提供了NodeIterator类型,使用它可以很方便地实现DOM树的先序遍历,《JavaScript高级程序设计第三版》的12.3.1节介绍了这个类型,我们这里直接给出代码如下:

/**
 * 使用DOM2的"Traversal"模块提供的NodeIterator先序遍历DOM树
 * @param node 根节点
 */
function traversalUsingNodeIterator(node){
  var iterator = document.createNodeIterator(node, NodeFilter.SHOW_ELEMENT,null,false);
  var node = iterator.nextNode();
  while(node != null){
    console.log(node.tagName);
    node = iterator.nextNode();
  }
}

5. 使用TreeWalker

TreeWalker类型可以说是NodeIterator类型的增强版,《JavaScript高级程序设计第三版》的12.3.2节介绍了这个类型,我们这里也直接给出代码如下:

/**
 * 使用DOM2的"Traversal"模块提供的TreeWalker先序遍历DOM树
 * @param node 根节点
 */
function traversalUsingTreeWalker(node){
  var treeWalker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT,null,false);
  if(node && node.nodeType === 1){
    console.log(node.tagName);
  }
  var node = treeWalker.nextNode();
  while(node != null){
    console.log(node.tagName);
    node = treeWalker.nextNode();
  }
}

以上就是为大家分享的javascript先序遍历DOM树的方法,希望对大家的学习有所帮助。

Javascript 相关文章推荐
jQuery 学习第六课 实现一个Ajax的TreeView
May 17 Javascript
jquery offset函数应用实例
Nov 14 Javascript
跟我学习javascript的循环
Nov 18 Javascript
jQuery实现的左右移动焦点图效果
Jan 14 Javascript
AngularJS中实现动画效果的方法
Jul 28 Javascript
jQuery UI制作选项卡(tabs)
Dec 13 Javascript
js实现兼容PC端和移动端滑块拖动选择数字效果
Feb 16 Javascript
基于angular实现模拟微信小程序swiper组件
Jun 11 Javascript
vue单个组件实现无限层级多选菜单功能
Apr 10 Javascript
JavaScript中var、let、const区别浅析
Jun 24 Javascript
JavaScript实现的九种排序算法
Mar 04 Javascript
layer更改皮肤的实现方法
Sep 11 Javascript
JavaScript开发者必备的10个Sublime Text插件
Feb 27 #Javascript
Javascript生成全局唯一标识符(GUID,UUID)的方法
Feb 27 #Javascript
JS原型、原型链深入理解
Feb 27 #Javascript
Javascript中Date类型和Math类型详解
Feb 27 #Javascript
原生javascript实现匀速运动动画效果
Feb 26 #Javascript
探索angularjs+requirejs全面实现按需加载的套路
Feb 26 #Javascript
JavaScript代码生成PDF文件的方法
Feb 26 #Javascript
You might like
php str_replace的替换漏洞
2008/03/15 PHP
PHP insert语法详解
2008/06/07 PHP
斜45度寻路实现函数
2009/08/20 Javascript
jQuery插件原来如此简单 jQuery插件的机制及实战
2012/02/07 Javascript
jQuery学习笔记之jQuery动画效果
2013/09/09 Javascript
基于jquery实现一张图片点击鼠标放大再点缩小
2013/09/29 Javascript
JavaScript中的函数重载深入理解
2014/08/04 Javascript
AngularJS基础知识
2014/12/21 Javascript
js判断文本框剩余可输入字数的方法
2015/02/04 Javascript
javascript 正则表达式去空行方法
2017/01/24 Javascript
简单实现js放大镜效果
2017/07/24 Javascript
基于Vuex无法观察到值变化的解决方法
2018/03/01 Javascript
vue实现选项卡及选项卡切换效果
2018/04/24 Javascript
前端防止用户重复提交js实现代码示例
2018/09/07 Javascript
js使用swiper实现层叠轮播效果实例代码
2018/12/12 Javascript
jQuery实现经典的网页3D轮播图封装功能【附源码下载】
2019/02/15 jQuery
关于Vue中axios的封装实例详解
2019/10/20 Javascript
JavaScript TAB栏切换效果的示例
2020/11/05 Javascript
[43:03]LGD vs Newbee 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
使用Python下载歌词并嵌入歌曲文件中的实现代码
2015/11/13 Python
python批量制作雷达图的实现方法
2016/07/26 Python
Python实现返回数组中第i小元素的方法示例
2017/12/04 Python
python将秒数转化为时间格式的实例
2018/09/16 Python
Python中对数组集进行按行打乱shuffle的方法
2018/11/08 Python
python使用magic模块进行文件类型识别方法
2018/12/08 Python
Python文件如何引入?详解引入Python文件步骤
2018/12/10 Python
python利用paramiko实现交换机巡检的示例
2020/09/22 Python
纯CSS3大转盘抽奖示例代码(响应式、可配置)
2017/01/13 HTML / CSS
N:Philanthropy官网:美国洛杉矶基础款服装
2020/06/09 全球购物
视图的作用
2014/12/19 面试题
参观监狱心得体会
2014/01/02 职场文书
学生期末评语大全
2014/04/30 职场文书
员工合理化建议书
2014/05/19 职场文书
文明城市创建标语
2014/06/16 职场文书
学校禁毒宣传活动总结
2015/05/08 职场文书
铁头也玩根德 YachtBoy YB-230......
2022/04/05 无线电