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 相关文章推荐
JavaScript中的Document文档对象
Jan 16 Javascript
js实现在文本框光标处添加字符的方法介绍
Nov 24 Javascript
js实现touch移动触屏滑动事件
Apr 17 Javascript
jQuery层动画定位滑动效果的方法
Apr 30 Javascript
javascript事件委托的用法及其好处简析
Apr 04 Javascript
Bootstrap CSS布局之按钮
Dec 17 Javascript
jQuery插件Echarts实现的渐变色柱状图
Mar 23 jQuery
jQuery Layer弹出层传值到父页面的实现代码
Aug 17 jQuery
React Native中Navigator的使用方法示例
Oct 13 Javascript
微信小程序如何引用外部js,外部样式,公共页面模板
Jul 23 Javascript
js实现中文实时时钟
Jan 15 Javascript
基于脚手架创建Vue项目实现步骤详解
Aug 03 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 网页过期时间的控制代码
2009/06/29 PHP
分享下页面关键字抓取components.arrow.com站点代码
2014/01/30 PHP
详解Laravel服务容器的绑定与解析
2019/11/05 PHP
区分JS中的undefined,null,&quot;&quot;,0和false
2007/03/08 Javascript
Jquery 组合form元素为json格式,asp.net反序列化
2009/07/09 Javascript
关于IE、Firefox、Opera页面呈现异同 写脚本很痛苦
2009/08/28 Javascript
jQuery中slideUp()方法用法分析
2014/12/24 Javascript
js简单实现点击左右运动的方法
2015/04/10 Javascript
window.onload使用指南
2015/09/13 Javascript
js H5 canvas投篮小游戏
2016/08/18 Javascript
js放大镜放大购物图片效果
2017/01/18 Javascript
jquery uploadify如何取消已上传成功文件
2017/02/08 Javascript
整理一些最近经常遇到的前端面试题
2017/04/25 Javascript
JavaScript如何获取到导航条中HTTP信息
2017/10/10 Javascript
javascript代码优化的8点总结
2018/01/29 Javascript
详解基于webpack&amp;gettext的前端多语言方案
2019/01/29 Javascript
JS实现求字符串中出现最多次数的字符和次数示例
2019/07/05 Javascript
jQuery实现轮播图源码
2019/10/23 jQuery
Python爬取网易云音乐热门评论
2017/03/31 Python
对python numpy数组中冒号的使用方法详解
2018/04/17 Python
Python连接Mssql基础教程之Python库pymssql
2018/09/16 Python
通过python的matplotlib包将Tensorflow数据进行可视化的方法
2019/01/09 Python
python实现坦克大战游戏 附详细注释
2020/03/27 Python
Python底层封装实现方法详解
2020/01/22 Python
python 实现围棋游戏(纯tkinter gui)
2020/11/13 Python
Python Http请求json解析库用法解析
2020/11/28 Python
利用HTML5 Canvas制作键盘及鼠标动画的实例分享
2016/03/15 HTML / CSS
PatPat香港:婴童服饰和亲子全家装在线购物
2020/09/27 全球购物
STP协议的主要用途是什么?为什么要用STP
2012/12/20 面试题
2014年出纳工作总结与计划
2014/12/09 职场文书
人事行政助理岗位职责
2015/04/11 职场文书
勇敢的心观后感
2015/06/09 职场文书
2016七一建党节慰问信
2015/11/30 职场文书
导游词之平津战役纪念馆
2019/11/04 职场文书
php中pcntl_fork详解
2021/04/01 PHP
js前端面试常见浏览器缓存强缓存及协商缓存实例
2022/06/21 Javascript