文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JavaScript 中怎么利用DOM实现文档遍历

2024-04-02 19:55

关注

本篇文章给大家分享的是有关JavaScript 中怎么利用DOM实现文档遍历,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

<!--<html>     <head>         <title>DOM Examlie</title>     </head>     <body>        <p>Hello World !</p> </body> </html>-->

访问<html>元素,你应该明白它是该文件的document元素,那你就可以使用document的documentElement属性:

var oHtml=document.documentElement;//可以直接访问<html>元素  alert("节点名称 : "+oHtml.nodeName);//节点名称  alert("节点类型 : "+oHtml.nodeType);//节点类型为 1

获取<head> 和 <body>元素:

var oHead=oHtml.firstChild;//HEAD节点  var oBody=oHtml.lastChild;//BODY节点

也可以通过childNodes属性,获取<head> 和 <body>元素:

var oHead=oHtml.childNodes.item(0);//HEAD节点  //var oHead=oHtml.childNodes[0];//简写,也有同样的结果是HEAD节点  var oBody=oHtml.childNodes.item(1);//BODY节点  //var oBody=oHtml.childNodes.item(1);//简写,也有同样的结果是BODY节点

注意:方括号标记其实是NodeList在javascript中的简便实现。实际上正式的从childNodes列表中获取子节点的方法是使用item()方法:HTML DOM 中的专有属性 document.body ,它常用于直接访问元素:

var oBody=document.body;

既然我们都知道了以上节点对象的获取方式,那我们用oHtml,oHead,oBody 这三个变量来确定一下它们之间的关系:

alert(oHead.parentNode==oHtml);//HEAD节点的父节点是BODY节点,返回 true   alert(oBody.parentNode==oHtml);//BODY节点的父节点是BODY节点,返回 true   alert(oBody.previousSibling==oHead);//BODY节点的上一个兄弟节点是HEAD节点 ,返回 true  alert(oHead.nextSibling==oBody);//HEAD节点的下一个兄弟节点是BODY节点,返回 true  alert(oHead.ownerDocument==document); //返回一个节点的根元素(Document),HEAD节点是否指向该文档,返回 true

通过上面的学习我们已经了解遍历节点的最基本的方式, 也学会了如何找到某一个节点的兄弟节点及它的子节点。

复杂的节点遍历

在上面的学习中我们好像没有遇到过大的阻碍,下面我们以一个“导航条”为实例:

<div id="menu">     <h2>我的导航条</h2>                <ul id="nav">        <li><a href="#">HOME</a></li>        <li><a href="#">(X)Html / Css</a></li>        <li><a href="#">Ajax / RIA</a></li>        <li><a href="#">GoF</a></li>        <li><a href="#">JavaScript</a></li>        <li><a href="#">JavaWeb</a></li>        <li><a href="#">jQuery</a></li>        <li><a href="#">MooTools</a></li>        <li><a href="#">Python</a></li>        <li><a href="#">Resources</a></li>     </ul> </div>

首先我想把看一下我的导航条下有多少个子节点。我***想到的是前面我学过的查找元素的2种方法:

getElementById() # 通过ID属性查找元素

该方法将返回一个与那个有着给定id属性值的元素节点相对应的对象。

getElementsByTagName() # 通过标签名称查找元素

该方法返回一个对象数组,每个对象分别对应着文档里有着给定标签的一个元素。

<script type="text/javascript">   function queryElementsId(){    var elemensArray,nav,nav_list;    elemensArray=[];    nav=document.getElementById("nav");           navnav_list=nav.childNodes;       for(var i=0;i<nav_list.length;i++){      elemensArray[elemensArray.length]=nav_list[i];      //elemensArray.push(nav_list[i]); //同上一样的结果       }    return elemensArray;     }    function queryElementsTagName(){   var elemensArray,nav,nav_list;   elemensArray=[];   var nav=document.getElementById("nav");   var navnav_list=nav.getElementsByTagName("li");//返回相同的一组元素   for(var i=0;i<nav_list.length;i++){    elemensArray[elemensArray.length]=nav_list[i];    //elemensArray.push(nav_list[i]); //同上一样的结果   }   return elemensArray;     }  </script>

节点遍历

那我们接下来,测一下是否是我们想要的东西:

<script type="text/javascript"> window.onload=function(){              var list= queryElementsId();        //var list= queryElementsTagName();    var s="";   for(var i=0;i<list.length;i++){    s+=list[i].nodeName+"\n";       }   alert(s);   }  </script>

先看一下***个方法queryElementsId()好像我们在IE中没有发现有什么问题,那我们在Firefox中看一下是否也是我们想要的结果。

这时,问题出现了,不同的浏览器在判断何为Text节点上存在着一些差异,例如在A级浏览器中的FF和IE就有很大的差异,FireFox会把元素之间的空白、换行、tab都是Text节点,IE下会把空白全部忽略掉,只有内联元素(如em,span)后的换行、空格、tab会被认为是一个Text。既然遇到了问题那我们就得解决问题,问题的根源我们也知道了,那相应的解决方案就好做了。

方法一:

<script type="text/javascript">      function cleanWhitespace(element){      //如果不提供参数,则处理整个HTML文档      elementelement = element || document;      //使用***个子节点作为开始指针      var cur = element.firstChild;         //一直到没有子节点为止      while (cur != null){          //如果节点为文本节点,应且包含空格          if ( cur.nodeType == && ! /\S/.test(cur.nodeValue)){              //删除这个文本节点              element.removeChild( cur );                 //否则,它就是一个元素          } else if (cur.nodeType == 1){              //递归整个文档              cleanWhitespace( cur );          }             curcur = cur.nextSibling;//遍历子节点      }  }  </script>

方法二:

<script type="text/javascript">         function cleanWhitespaces(elem){      //如果不提供参数,则处理整个HTML文档   var elemelem = elem || document;    var parentElem = elem.parentNode; //返回一个节点的父类节点   var childElem = parentElem.childNodes; //返回一个节点的子节点的节点列表   var childElemArray = new Array;    for (var i=0; i<childElem.length; i++){    if (childElem[i].nodeType==1){//把所有节点是元素节点类型的节点存放到数组里     childElemArray.push(childElem[i]);     }   }      return childElemArray;   }   </script>

方法三:推荐

<script type="text/javascript">   function removeWhitespace(xml){      var loopIndex;         for (loopIndex = 0; loopIndex < xml.childNodes.length; loopIndex++){          var currentNode = xml.childNodes[loopIndex];          if (currentNode.nodeType == 1){              removeWhitespace(currentNode);          }             if (((/^\s+$/.test(currentNode.nodeValue))) &&(currentNode.nodeType == 3)){              xml.removeChild(xml.childNodes[loopIndex--]);          }      }  }  </script>

好了,我们在验证一下,#Text节点问题是否处理掉了。那我们就用方法3 中removeWhitespace(nav)方法来处理queryElementsId()方法中的#Text节点问题。

<script type="text/javascript"> function queryElementsId(){    var elemensArray,nav,nav_list;    elemensArray=[];    nav=document.getElementById("nav");        removeWhitespace(nav);              navnav_list=nav.childNodes;       for(var i=0;i<nav_list.length;i++){      elemensArray[elemensArray.length]=nav_list[i];      //elemensArray.push(nav_list[i]); //同上一样的结果       }    return elemensArray;     }  </script>

正如看到的结果,IE和FireFox中都没有问题了。

一个比较通用的方法:

<script type="text/javascript"> function text(elem){   var t="";   //如果传入的是元素,则继续遍历其子元素   //否则假定它是一个数组   elemelem=elem.childNodes || elem;   //遍历所有子节点   for(var i=0; i<elem.length;i++){       //如果不是元素,追加其文本值    //否则,递归遍历所有元素的子节点    t+=elem[i].nodeType !=1?elem[i].nodeValue:text(elem[i].childNodes);      }      //返回比配的文本      return t;  }  </script>

用元素节点的DOM属性遍历DOM树

<script type="text/javascript"> window.onload=function(){        var nav=document.getElementById("nav");        var p_n=nav.parentNode;    alert("父节点的元素名称:"+p_n.nodeName);           removeWhitespace(nav);//移除所有的空Text节点             var c_n_f=nav.firstChild;/        var c_n_s=c_n_f.nextSibling;//***个节点的下一个节点    alert("***个节点的下一个节点:"+c_n_s.innerHTML+ "\n" + "节点中包含的HTML内容: "+c_n_s.nodeName);     }  </script>

写到这里,既然标准的previousSibling,nextSibling,firstChild,lastChild,parentNode遍历方法有浏览器不兼容问题。我上面的解决方案是去掉遍历元素的相关空的#Text节点,是一个好的解决方案,但是使用起来不方便,我们何不自己写一些遍历节点的方法来代替标准的的previousSibling,nextSibling,firstChild,lastChild,parentNode。

我们的思路是利用元素是nodeType属性来判断元素是节点类型中那种节点类型,在DOM节点中我最常用的是元素节点,文本节点,属性节点,对应的类型值是元素节点nodeType=1 or ELEMENT_NODE, 文本节点 nodeType=2 or ATTRIBUTE_NODE,属性节点 nodeType=3 or TEXT_NODE,但是IE中并不支持命名常量,那就用数值吧,再配合标准的遍历属性。完全可以自己生产一些辅助函数来取代标准的遍历方式。以下一系列的辅助函数可以帮助您,他们能取代标准的previousSibling,nextSibling,firstChild,lastChild,parentNode;

<script type="text/javascript"> //---------DOM 遍历,如果元素没找到则返回null---------//          //---查找相关元素的前一个兄弟元素---//         function prev(elem){              do{                 elemelem=elem.previousSibling;              }while(elem && elem.nodeType!=1);              return elem;          }          //---查找相关元素的下一个兄弟元素---//          function next(elem){             do{                 elemelem=elem.nextSibling;              }while(elem && elem.nodeType!=1);              return elem;          }          //---查找***个子元素的函数---//          function first(elem){              elemelem=elem.firstChild;              return elem && elem.nodeType!=1 ?next(elem):elem;          }          //---查找***一个子元素的函数---//          function last(elem){              elemelem=elem.lastChild;              return elem && elem.nodeType!=1 ?prev(elem):elem;          }          //---查找父级元素的函数---//          //num是父级元素的级次,parent(elem,2)等价于     function parent(elem,num){              numnum=num||1;              for(var i=0; i<num; i++){                  if(elem!=null){                      elemelem=elem.parentNode;                 }              }             return elem;         }   </script>

以上就是JavaScript 中怎么利用DOM实现文档遍历,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯