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 相关文章推荐
js中定义一个变量并判断其是否为空的方法
May 13 Javascript
wap浏览自动跳转到wap页面的js代码
May 17 Javascript
手机开发必备技巧:javascript及CSS功能代码分享
May 25 Javascript
基于jQuery+JSON的省市二三级联动效果
Jun 05 Javascript
php利用curl获取远程图片实现方法
Oct 26 Javascript
原生javascript实现解析XML文档与字符串
Mar 01 Javascript
再次谈论Javascript中的this
Jun 23 Javascript
详解vue静态资源打包中的坑与解决方案
Feb 05 Javascript
JS简单实现查看文档创建日期、修改日期和文档大小的方法示例
Apr 08 Javascript
小程序清理本地缓存的方法
Aug 17 Javascript
详解Element 指令clickoutside源码分析
Feb 15 Javascript
vue项目移动端实现ip输入框问题
Mar 19 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
我的论坛源代码(一)
2006/10/09 PHP
php桌面中心(二) 数据库写入
2007/03/11 PHP
php中配置文件操作 如config.php文件的读取修改等操作
2012/07/07 PHP
php 获取本地IP代码
2013/06/23 PHP
支付宝支付开发――当面付条码支付和扫码支付实例
2016/11/04 PHP
PHP读取word文档的方法分析【基于COM组件】
2017/08/01 PHP
jquery获取ASP.NET服务器端控件dropdownlist和radiobuttonlist生成客户端HTML标签后的value和text值
2010/06/28 Javascript
瀑布流布局代码一例
2014/04/11 Javascript
js实现文字在按钮上滚动的方法
2015/08/20 Javascript
浅谈angularjs中响应回车事件
2017/04/24 Javascript
基于zepto.js实现手机相册功能
2017/07/11 Javascript
React.Js添加与删除onScroll事件的方法详解
2017/11/03 Javascript
基于Node.js实现压缩和解压缩的方法
2018/02/13 Javascript
微信小程序实现省市区三级地址选择
2020/06/21 Javascript
angular 表单验证器验证的同时限制输入的实现
2019/04/11 Javascript
Vue 之孙组件向爷组件通信的实现
2019/04/23 Javascript
微信小程序实现页面浮动导航
2020/01/08 Javascript
Python获取远程文件大小的函数代码分享
2014/05/13 Python
Python 判断图像是否读取成功的方法
2019/01/26 Python
Django页面数据的缓存与使用的具体方法
2019/04/23 Python
python matplotlib实现将图例放在图外
2020/04/17 Python
Python虚拟环境库virtualenvwrapper安装及使用
2020/06/17 Python
python爬虫看看虎牙女主播中谁最“顶”步骤详解
2020/12/01 Python
分享全球十款超强HTML5开发工具
2014/05/14 HTML / CSS
Falconeri美国官网:由羊绒和羊毛制成的针织服装
2018/04/08 全球购物
意大利体育用品和运动服网上商店:Maxi Sport
2019/09/14 全球购物
英国运动服、设备及配件网站:DW Sports
2019/12/04 全球购物
linux面试题参考答案(5)
2014/09/01 面试题
学生自我鉴定
2013/12/18 职场文书
后勤部经理岗位职责
2014/02/23 职场文书
我爱我校演讲稿
2014/05/21 职场文书
人力资源管理专业求职信
2014/07/23 职场文书
领导班子四风问题对照检查材料
2014/09/27 职场文书
党的群众路线教育实践活动领导班子整改方案
2014/10/25 职场文书
单位接收函格式
2015/01/30 职场文书
公司员工宿舍管理制度
2015/08/03 职场文书