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 EasyUI API 中文文档 - Parser 解析器
Sep 29 Javascript
ie6下png图片背景不透明的解决办法使用js实现
Jan 11 Javascript
javascript获取所有同类checkbox选项(实例代码)
Nov 07 Javascript
鼠标悬浮显示二级菜单效果的jquery实现
Oct 29 Javascript
jQuery随机密码生成的方法
Mar 09 Javascript
JavaScript实现快速排序的方法
Jul 31 Javascript
vue2.x select2 指令封装详解
Oct 12 Javascript
vue2.0 子组件改变props值,并向父组件传值的方法
Mar 01 Javascript
vue基于mint-ui实现城市选择三级联动
Jun 30 Javascript
vue2.0项目实现路由跳转的方法详解
Jun 21 Javascript
解决Layui数据表格中checkbox位置不居中的方法
Aug 15 Javascript
详解小程序BackgroundAudioManager踩坑之旅
Dec 08 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中关于php.ini参数优化详解
2020/02/28 PHP
js滚动条多种样式,推荐
2007/02/05 Javascript
js中的push和join方法使用介绍
2013/10/08 Javascript
jQuery中get和post方法传值测试及注意事项
2014/08/08 Javascript
浅析js预加载/延迟加载
2014/09/25 Javascript
jquery中show()、hide()和toggle()用法实例
2015/01/15 Javascript
jquery实现带缩略图的全屏图片画廊效果实例
2015/06/25 Javascript
快速学习jQuery插件 Cookie插件使用方法
2015/12/01 Javascript
swiper插件自定义切换箭头按钮
2017/12/28 Javascript
JS实现的合并多个数组去重算法示例
2018/04/11 Javascript
实例讲解JavaScript截取字符串
2018/11/30 Javascript
了解javascript中变量及函数的提升
2019/05/27 Javascript
在Vue项目中,防止页面被缩放和放大示例
2019/10/28 Javascript
JS实现页面侧边栏效果探究
2021/01/08 Javascript
详解Vue3.0 + TypeScript + Vite初体验
2021/02/22 Vue.js
跟老齐学Python之通过Python连接数据库
2014/10/28 Python
Python基础练习之用户登录实现代码分享
2017/11/08 Python
pygame游戏之旅 添加键盘按键的方法
2018/11/20 Python
python实现根据文件关键字进行切分为多个文件的示例
2018/12/10 Python
Python3标准库总结
2019/02/19 Python
Python之NumPy(axis=0 与axis=1)区分详解
2019/05/27 Python
Windows下PyCharm配置Anaconda环境(超详细教程)
2020/07/31 Python
Python+Opencv身份证号码区域提取及识别实现
2020/08/25 Python
西班牙购买隐形眼镜、眼镜和太阳镜网站:Lentiamo.es
2020/06/11 全球购物
物业管理公司实习生自我鉴定
2013/09/19 职场文书
小学数学教学反思
2014/02/02 职场文书
法学函授自我鉴定
2014/02/06 职场文书
质量标语大全
2014/06/12 职场文书
护士工作失误检讨书
2014/09/14 职场文书
浪漫婚礼主题活动策划方案
2014/09/15 职场文书
2014市府办领导班子“四风问题”对照检查材料思想汇报
2014/09/24 职场文书
五年级小学生评语
2014/12/26 职场文书
毕业论文致谢怎么写
2015/05/14 职场文书
行政处罚告知书
2015/07/01 职场文书
小学生安全教育心得体会
2016/01/15 职场文书
详细介绍python操作RabbitMq
2022/04/12 Python