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 相关文章推荐
html5的自定义data-*属性和jquery的data()方法的使用示例
Aug 21 Javascript
JQuery弹出炫丽对话框的同时让背景变灰色
May 22 Javascript
vue.js+boostrap项目实践(案例详解)
Sep 21 Javascript
Angularjs之filter过滤器(推荐)
Nov 27 Javascript
利用Jquery实现几款漂亮实用的时间轴(附示例代码)
Feb 15 Javascript
JS简单实现点击按钮或文字显示遮罩层的方法
Apr 27 Javascript
荐书|您有一份JavaScript书单待签收
Jul 21 Javascript
vue框架搭建之axios使用教程
Jul 11 Javascript
axios取消请求的实践记录分享
Sep 26 Javascript
layer更改皮肤的实现方法
Sep 11 Javascript
小程序使用分包的示例代码
Mar 23 Javascript
Javascript前端下载后台传来的文件流代码实例
Aug 18 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图片处理:加水印、缩略图的实现(自定义函数:watermark、thumbnail)
2010/12/02 PHP
10个超级有用值得收藏的PHP代码片段
2015/01/22 PHP
PHP微信开发之根据用户回复关键词\位置返回附近信息
2016/06/24 PHP
php封装的单文件(图片)上传类完整实例
2016/10/18 PHP
php设计模式之备忘模式分析【星际争霸游戏案例】
2020/03/24 PHP
理解Javascript_09_Function与Object
2010/10/16 Javascript
jqPlot 图表中文API使用文档及源码和在线示例
2012/02/07 Javascript
浅谈Javascript事件模拟
2012/06/27 Javascript
js清除input中type等于file的值域(示例代码)
2013/12/24 Javascript
js验证电话号码与手机支持+86的正则表达式
2014/01/23 Javascript
Vue框架中正确引入JS库的方法介绍
2017/07/30 Javascript
vue操作下拉选择器获取选择的数据的id方法
2018/08/24 Javascript
详解vue 路由跳转四种方式 (带参数)
2019/04/28 Javascript
react 生命周期实例分析
2020/05/18 Javascript
nuxt 服务器渲染动态设置 title和seo关键字的操作
2020/11/05 Javascript
全面了解Python的getattr(),setattr(),delattr(),hasattr()
2016/06/14 Python
python制作mysql数据迁移脚本
2019/01/01 Python
python3正则提取字符串里的中文实例
2019/01/31 Python
Python 最强编辑器详细使用指南(PyCharm )
2019/09/16 Python
Python实现自定义读写分离代码实例
2019/11/16 Python
Python3基本输入与输出操作实例分析
2020/02/14 Python
pyautogui自动化控制鼠标和键盘操作的步骤
2020/04/01 Python
Python logging模块写入中文出现乱码
2020/05/21 Python
Python中SQLite如何使用
2020/05/27 Python
用python爬虫批量下载pdf的实现
2020/12/01 Python
一个非常简单好用的Python图形界面库(PysimpleGUI)
2020/12/28 Python
CSS3 filter(滤镜)实现网页灰色或者黑色模式的代码
2020/11/30 HTML / CSS
汽修专业学生自我鉴定
2013/11/16 职场文书
关于幼儿的自我评价
2013/12/18 职场文书
打造完美自荐信
2014/01/24 职场文书
2014年人事行政工作总结
2014/12/03 职场文书
毕业生就业推荐表自我评价
2015/03/02 职场文书
关于调整工作时间的通知
2015/04/24 职场文书
Vue CLI中模式与环境变量的深入详解
2021/05/30 Vue.js
解析MySQL索引的作用
2022/03/03 MySQL
插件导致ECharts被全量引入的坑示例解析
2022/09/23 Javascript