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 相关文章推荐
找到一点可怜的关于dojo资料,谢谢作者!
Dec 06 Javascript
基于jquery的图片幻灯展示源码
Jul 15 Javascript
js实现弹窗插件功能实例代码分享
Dec 12 Javascript
JQuery仿小米手机抢购页面倒计时效果
Dec 16 Javascript
js随机生成字母数字组合的字符串 随机动画数字
Sep 02 Javascript
JavaScript头像上传插件源码分享
Mar 29 Javascript
JSON在Javascript中的使用(eval和JSON.parse的区别)详细解析
Sep 05 Javascript
基于js中style.width与offsetWidth的区别(详解)
Nov 12 Javascript
实例解析ES6 Proxy使用场景介绍
Jan 08 Javascript
ES6知识点整理之模块化的应用详解
Apr 15 Javascript
Vue接口封装的完整步骤记录
May 14 Vue.js
利用JavaScript写一个简单计算器
Nov 27 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 无限级数据JSON格式及JS解析
2010/07/17 PHP
PHP array_multisort()函数的使用札记
2011/07/03 PHP
通过php快速统计某个数据库中每张表的数据量
2012/09/04 PHP
解决cPanel无法安装php5.2.17
2014/06/22 PHP
PHP 快速排序算法详解
2014/11/10 PHP
优化WordPress的Google字体以加速国内服务器上的运行
2015/11/24 PHP
PHP Oauth授权和本地加密实现方法
2016/08/12 PHP
PHP入门教程之面向对象的特性分析(继承,多态,接口,抽象类,抽象方法等)
2016/09/11 PHP
PHP __call()方法实现委托示例
2019/05/20 PHP
jquery ajax return没有返回值的解决方法
2011/10/20 Javascript
为原生js Array增加each方法
2012/04/07 Javascript
单击浏览器右上角的X关闭窗口弹出提示的小例子
2013/06/12 Javascript
js的隐含参数(arguments,callee,caller)使用方法
2014/01/28 Javascript
javascript 获取HTML DOM父、子、临近节点
2014/06/16 Javascript
node.js中的fs.writeFile方法使用说明
2014/12/14 Javascript
jQuery实用技巧必备(中)
2015/11/03 Javascript
window.onload绑定多个事件的两种解决方案
2016/05/15 Javascript
很棒的js选项卡切换效果
2016/07/15 Javascript
BootStrap 模态框实现刷新网页并关闭功能
2017/01/04 Javascript
浅谈angular4 ng-content 中隐藏的内容
2017/08/18 Javascript
JS图片延迟加载插件LazyImgv1.0用法分析【附demo源码下载】
2017/09/04 Javascript
微信小程序实现漂亮的弹窗效果
2020/05/26 Javascript
require.js 加载过程与使用方法介绍
2018/10/30 Javascript
Python中Random和Math模块学习笔记
2015/05/18 Python
浅谈Python中copy()方法的使用
2015/05/21 Python
python入门教程之识别验证码
2017/03/04 Python
windows下python 3.6.4安装配置图文教程
2018/08/21 Python
python 对key为时间的dict排序方法
2018/10/17 Python
Python中logging日志的四个等级和使用
2020/11/17 Python
Python将QQ聊天记录生成词云的示例代码
2021/02/10 Python
公关活动策划方案
2014/05/25 职场文书
车间安全生产标语
2014/06/06 职场文书
小学信息技术教学反思
2016/02/16 职场文书
python数据分析之用sklearn预测糖尿病
2021/04/22 Python
CSS实现两列布局的N种方法
2021/08/02 HTML / CSS
oracle设置密码复杂度及设置超时退出的功能
2022/06/28 Oracle