成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

JavaScript DOM文檔遍歷實戰

開發 前端
文章將介紹JavaScript DOM文檔遍歷的操作方法,其中比較復雜的是節點遍歷,閱讀本文您需要對HTML頁面的主要元素和屬性有深入的了解。

在介紹了《JavaScript DOM修改文檔樹方法實例》與《JavaScript DOM實戰:創建和克隆元素》,本文將介紹JavaScript DOM文檔遍歷的詳細知識,我們先從HTML頁面最基本的組成元素討論起:

  1. <!--<html> 
  2.     <head> 
  3.         <title>DOM Examlie</title> 
  4.     </head> 
  5.     <body> 
  6.        <p>Hello World !</p> 
  7. </body> 
  8. </html>-->  

訪問<html>元素,你應該明白它是該文件的document元素,那你就可以使用document的documentElement屬性:

  1. var oHtml=document.documentElement;//可以直接訪問<html>元素  
  2. alert("節點名稱 : "+oHtml.nodeName);//節點名稱  
  3. alert("節點類型 : "+oHtml.nodeType);//節點類型為 1  

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

  1. var oHead=oHtml.firstChild;//HEAD節點  
  2. var oBody=oHtml.lastChild;//BODY節點  

也可以通過childNodes屬性,獲取<head> 和 <body>元素:

  1. var oHead=oHtml.childNodes.item(0);//HEAD節點  
  2. //var oHead=oHtml.childNodes[0];//簡寫,也有同樣的結果是HEAD節點  
  3. var oBody=oHtml.childNodes.item(1);//BODY節點  
  4. //var oBody=oHtml.childNodes.item(1);//簡寫,也有同樣的結果是BODY節點  

注意:方括號標記其實是NodeList在javascript中的簡便實現。實際上正式的從childNodes列表中獲取子節點的方法是使用item()方法:HTML DOM 中的專有屬性 document.body ,它常用于直接訪問元素:

  1. var oBody=document.body;  

既然我們都知道了以上節點對象的獲取方式,那我們用oHtml,oHead,oBody 這三個變量來確定一下它們之間的關系:

  1. alert(oHead.parentNode==oHtml);//HEAD節點的父節點是BODY節點,返回 true   
  2. alert(oBody.parentNode==oHtml);//BODY節點的父節點是BODY節點,返回 true   
  3. alert(oBody.previousSibling==oHead);//BODY節點的上一個兄弟節點是HEAD節點 ,返回 true  
  4. alert(oHead.nextSibling==oBody);//HEAD節點的下一個兄弟節點是BODY節點,返回 true  
  5. alert(oHead.ownerDocument==document); //返回一個節點的根元素(Document),HEAD節點是否指向該文檔,返回 true  

通過上面的學習我們已經了解遍歷節點的最基本的方式, 也學會了如何找到某一個節點的兄弟節點及它的子節點。

#p#

復雜的節點遍歷

在上面的學習中我們好像沒有遇到過大的阻礙,下面我們以一個“導航條”為實例:

  1. <div id="menu"> 
  2.     <h1>我的導航條</h1>            
  3.     <ul id="nav"> 
  4.        <li><a href="#">HOME</a></li> 
  5.        <li><a href="#">(X)Html / Css</a></li> 
  6.        <li><a href="#">Ajax / RIA</a></li> 
  7.        <li><a href="#">GoF</a></li> 
  8.        <li><a href="#">JavaScript</a></li> 
  9.        <li><a href="#">JavaWeb</a></li> 
  10.        <li><a href="#">jQuery</a></li> 
  11.        <li><a href="#">MooTools</a></li> 
  12.        <li><a href="#">Python</a></li> 
  13.        <li><a href="#">Resources</a></li> 
  14.     </ul> 
  15. </div>  

首先我想把看一下我的導航條下有多少個子節點。我***想到的是前面我學過的查找元素的2種方法:

getElementById() # 通過ID屬性查找元素

該方法將返回一個與那個有著給定id屬性值的元素節點相對應的對象。

getElementsByTagName() # 通過標簽名稱查找元素

該方法返回一個對象數組,每個對象分別對應著文檔里有著給定標簽的一個元素。

  1. <script type="text/javascript"> 
  2. /*  
  3. 通過ID屬性查找元素 ,用的是文檔對象的getElementById()方法,  
  4. 查找到我們想要的元素對象,根據這個節點元素的 childNodes 屬性,  
  5. 遍歷出所有的子節點對象。  
  6. */  
  7. function queryElementsId(){  
  8.   var elemensArray,nav,nav_list;  
  9.   elemensArray=[];  
  10.   nav=document.getElementById("nav");  
  11.   /*注意IE和FF中處理Text節點上存在著一些差異*/  
  12.      navnav_list=nav.childNodes;  
  13.      for(var i=0;i<nav_list.length;i++){  
  14.     elemensArray[elemensArray.length]=nav_list[i];  
  15.     //elemensArray.push(nav_list[i]); //同上一樣的結果  
  16.      }  
  17.   return elemensArray;  
  18.    
  19. }  
  20. /*  
  21. 我們觀察到我的導航條是有規律的,是用無序列表元素組成的,只有定位到 &lt;ul&gt;元素  
  22. ;然后把getElementsByTagName()方法可以返回相同元素對象的集合,  
  23. 查用它找一組元素,太方便了。  
  24. */  
  25. function queryElementsTagName(){  
  26.  var elemensArray,nav,nav_list;  
  27.  elemensArray=[];  
  28.  var nav=document.getElementById("nav");  
  29.  var navnav_list=nav.getElementsByTagName("li");//返回相同的一組元素  
  30.  for(var i=0;i<nav_list.length;i++){  
  31.   elemensArray[elemensArray.length]=nav_list[i];  
  32.   //elemensArray.push(nav_list[i]); //同上一樣的結果  
  33.  }  
  34.  return elemensArray;  
  35.    
  36. }  
  37. </script>  

節點遍歷

那我們接下來,測一下是否是我們想要的東西:

  1. <script type="text/javascript"> 
  2. window.onload=function(){  
  3.      /****個方法*/  
  4.      var listqueryElementsId();   
  5.   /*第二個方法*/  
  6.  //var listqueryElementsTagName();   
  7.  var s="";  
  8.  for(var i=0;i<list.length;i++){  
  9.   s+=list[i].nodeName+"\n";   
  10.     }  
  11.  alert(s);  
  12.  }  
  13. </script>  

先看一下***個方法queryElementsId()好像我們在IE中沒有發現有什么問題,那我們在Firefox中看一下是否也是我們想要的結果。

這時,問題出現了,不同的瀏覽器在判斷何為Text節點上存在著一些差異,例如在A級瀏覽器中的FF和IE就有很大的差異,FireFox會把元素之間的空白、換行、tab都是Text節點,IE下會把空白全部忽略掉,只有內聯元素(如em,span)后的換行、空格、tab會被認為是一個Text。既然遇到了問題那我們就得解決問題,問題的根源我們也知道了,那相應的解決方案就好做了。

方法一:

  1. <script type="text/javascript"> 
  2. /*  
  3. 《精通javascript》上提供了一個函數,用于處理xm中的這些空格,其作用原理就是找出文本節點,并刪除這些節點,以達到刪除這些空格的目的。  
  4. */  
  5.    
  6. function cleanWhitespace(element){  
  7.     //如果不提供參數,則處理整個HTML文檔  
  8.     elementelement = element || document;  
  9.     //使用***個子節點作為開始指針  
  10.     var cur = element.firstChild;  
  11.    
  12.     //一直到沒有子節點為止  
  13.     while (cur != null){  
  14.         //如果節點為文本節點,應且包含空格  
  15.         if ( cur.nodeType == && ! /\S/.test(cur.nodeValue)){  
  16.             //刪除這個文本節點  
  17.             element.removeChild( cur );  
  18.    
  19.             //否則,它就是一個元素  
  20.         } else if (cur.nodeType == 1){  
  21.             //遞歸整個文檔  
  22.             cleanWhitespace( cur );  
  23.         }  
  24.    
  25.         curcur = cur.nextSibling;//遍歷子節點  
  26.     }  
  27. }  
  28. </script>  

方法二:

  1. <script type="text/javascript"> 
  2.    
  3. /*  
  4. ***,利用數組寫了一個函數,能夠有效的處理dom中的空格,其原理就是將一個元素的的父元素找出來,然后通過它父元素的childNodes屬性找出該元素的所有兄弟元素。遍歷該元素和它的兄弟元素,將所有元素節點放在一個數組里。這樣調用這個數組,就只有元素節點而沒有文本節點,也就沒有了討厭的空格.  
  5.    
  6. */  
  7.    
  8. function cleanWhitespaces(elem){  
  9.     //如果不提供參數,則處理整個HTML文檔  
  10.  var elemelem = elem || document;   
  11.  var parentElem = elem.parentNode; //返回一個節點的父類節點  
  12.  var childElem = parentElem.childNodes; //返回一個節點的子節點的節點列表  
  13.  var childElemArray = new Array;   
  14.  for (var i=0; i<childElem.length; i++){  
  15.   if (childElem[i].nodeType==1){//把所有節點是元素節點類型的節點存放到數組里  
  16.    childElemArray.push(childElem[i]);   
  17.   }  
  18.  }  
  19.     return childElemArray;   
  20. }   
  21. </script>  

方法三:推薦

  1. <script type="text/javascript"> 
  2. /*  
  3. 原理是對元素的所有的子節點做一個遍歷。然后做一個判斷,如果是子元素節點(nodeType = 1),則遍歷該子元素的所有的子節點,用遞歸檢查是否包含空白節點;如果處理的子節點是文本節點(nodeType = 3),則檢查是否是純粹的空白節點,如果是,就將它從xml對象中刪除。  
  4. */  
  5. function removeWhitespace(xml){  
  6.     var loopIndex;  
  7.    
  8.     for (loopIndex = 0; loopIndex < xml.childNodes.length; loopIndex++){  
  9.         var currentNode = xml.childNodes[loopIndex];  
  10.         if (currentNode.nodeType == 1){  
  11.             removeWhitespace(currentNode);  
  12.         }  
  13.    
  14.         if (((/^\s+$/.test(currentNode.nodeValue))) &&(currentNode.nodeType == 3)){  
  15.             xml.removeChild(xml.childNodes[loopIndex--]);  
  16.         }  
  17.     }  
  18. }  
  19. </script>  

好了,我們在驗證一下,#Text節點問題是否處理掉了。那我們就用方法3 中removeWhitespace(nav)方法來處理queryElementsId()方法中的#Text節點問題。

  1. <script type="text/javascript"> 
  2. function queryElementsId(){  
  3.   var elemensArray,nav,nav_list;  
  4.   elemensArray=[];  
  5.   nav=document.getElementById("nav");  
  6.   /*處理#Text節點問題*/  
  7.   removeWhitespace(nav);  
  8.    
  9.   /*注意IE和FF中處理Text節點上存在著一些差異*/  
  10.      navnav_list=nav.childNodes;  
  11.      for(var i=0;i<nav_list.length;i++){  
  12.     elemensArray[elemensArray.length]=nav_list[i];  
  13.     //elemensArray.push(nav_list[i]); //同上一樣的結果  
  14.      }  
  15.   return elemensArray;  
  16.    
  17. }  
  18. </script>  

正如看到的結果,IE和FireFox中都沒有問題了。

#p#

一個比較通用的方法:

  1. <script type="text/javascript"> 
  2. function text(elem){  
  3.  var t="";  
  4.  //如果傳入的是元素,則繼續遍歷其子元素  
  5.  //否則假定它是一個數組  
  6.  elemelem=elem.childNodes || elem;  
  7.  //遍歷所有子節點  
  8.  for(var i=0; i<elem.length;i++){  
  9.      //如果不是元素,追加其文本值  
  10.   //否則,遞歸遍歷所有元素的子節點  
  11.   t+=elem[i].nodeType !=1?elem[i].nodeValue:text(elem[i].childNodes);  
  12.    
  13.  }  
  14.     //返回比配的文本  
  15.     return t;  
  16. }  
  17. </script> 

用元素節點的DOM屬性遍歷DOM樹

  1. <script type="text/javascript"> 
  2. window.onload=function(){  
  3.   /*定位想要的節點*/  
  4.   var nav=document.getElementById("nav");  
  5.   /*查找父節點*/  
  6.   var p_n=nav.parentNode;  
  7.   alert("父節點的元素名稱:"+p_n.nodeName);  
  8.    
  9.   /*處理FF遍歷節點中的#Text */  
  10.   removeWhitespace(nav);//移除所有的空Text節點  
  11.    
  12.   /*查找子節點*/    
  13.   var c_n_f=nav.firstChild;//***個節點對象  
  14.   //var c_n_f=nav.childNodes[0];//同上一樣的結果  
  15.   var c_n_l=nav.lastChild;//***一個節點對象  
  16.   //var c_n_l=nav.childNodes[nav.childNodes.length-1];//同上一樣的結果  
  17.   alert("***個節點:"+c_n_f.nodeName+"  "+"***一個節點 :"+c_n_l.nodeName);   
  18.   /*查找兄弟節點 或叫 相鄰節點 */  
  19.   /*用nextSibling和PreviousSibling必須有一個參考點,這樣指針才知道自己往那里移動*/  
  20.   var c_n_s=c_n_f.nextSibling;//***個節點的下一個節點  
  21.   alert("***個節點的下一個節點:"+c_n_s.innerHTML+ "\n" + "節點中包含的HTML內容: "+c_n_s.nodeName);  
  22.    
  23. }  
  24. </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;

  1. <script type="text/javascript"> 
  2. //---------DOM 遍歷,如果元素沒找到則返回null---------//      
  3.     //---查找相關元素的前一個兄弟元素---//      
  4.    function prev(elem){      
  5.         do{      
  6.            elemelem=elem.previousSibling;      
  7.         }while(elem && elem.nodeType!=1);      
  8.         return elem;      
  9.     }      
  10.     //---查找相關元素的下一個兄弟元素---//      
  11.     function next(elem){      
  12.        do{      
  13.            elemelem=elem.nextSibling;      
  14.         }while(elem && elem.nodeType!=1);      
  15.         return elem;      
  16.     }      
  17.     //---查找***個子元素的函數---//      
  18.     function first(elem){      
  19.         elemelem=elem.firstChild;      
  20.         return elem && elem.nodeType!=1 ?next(elem):elem;      
  21.     }      
  22.     //---查找***一個子元素的函數---//      
  23.     function last(elem){      
  24.         elemelem=elem.lastChild;      
  25.         return elem && elem.nodeType!=1 ?prev(elem):elem;      
  26.     }      
  27.     //---查找父級元素的函數---//      
  28.     //num是父級元素的級次,parent(elem,2)等價于  
  29.    function parent(elem,num){      
  30.         numnum=num||1;      
  31.         for(var i=0; i<num; i++){      
  32.             if(elem!=null){      
  33.                 elemelem=elem.parentNode;      
  34.            }      
  35.         }      
  36.        return elem;      
  37.    }   
  38. </script> 

原文鏈接:http://cssrainbow.cn/tutorials/javascript/565.html

【編輯推薦】

  1. JavaScript DOM特性與應用詳解
  2. JavaScript DOM修改文檔樹方法實例
  3. JavaScript DOM實戰:創建和克隆元素 
責任編輯:王曉東 來源: cssrainbow
相關推薦

2010-09-28 14:35:34

DOM遍歷

2010-09-10 14:12:07

JavaScript

2010-09-10 13:06:27

JavaScript

2012-06-27 09:44:28

ibmdw

2021-01-11 07:51:16

DOM對象節點樹

2021-09-09 10:26:26

Javascript 文檔對象前端

2010-09-28 14:44:56

遍歷DOM

2010-09-08 17:26:46

JavaScript

2010-09-28 14:12:50

Javascript

2010-09-13 17:12:55

JavaScript

2010-09-28 10:03:15

DOM文檔對象模型

2012-04-26 08:29:22

DOM

2010-09-09 13:55:47

XML DOM

2010-09-28 09:43:37

DOM文檔對象模型

2010-09-28 13:24:34

DOM文檔對象模型

2010-09-28 11:03:19

XML DOM

2017-07-19 14:26:01

前端JavaScriptDOM

2010-09-10 16:21:58

JavaScript

2009-06-23 14:17:00

Dom4j

2014-02-24 14:45:23

XPath開發工具
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人国产在线观看 | www.47久久青青| 欧美日韩一区精品 | 久久久精品一区二区三区 | 黄视频免费在线 | 亚洲 欧美 日韩在线 | 一二三区视频 | 91综合在线视频 | 亚洲三级av | 在线免费观看a级片 | 成人乱人乱一区二区三区软件 | 狠狠干网站| 中文字幕精品一区 | 国产精品美女久久久久久免费 | 欧美视频免费 | 午夜免费福利电影 | 精品亚洲国产成av人片传媒 | 色综合久久天天综合网 | 国产专区在线 | 欧美性久久 | 国产一区二区三区视频在线观看 | 成人福利片 | 欧美久久视频 | 国产99久久久国产精品 | 岛国午夜| 欧美一卡二卡在线观看 | 欧美日韩精品在线一区 | 国产一级在线 | 蜜臀久久99精品久久久久野外 | 日本亚洲一区二区 | 四虎永久免费影院 | 亚洲天堂中文字幕 | 午夜一级做a爰片久久毛片 精品综合 | 亚洲欧美综合 | 国产精品亚洲欧美日韩一区在线 | 亚洲高清成人在线 | 成人国产精品一级毛片视频毛片 | 免费久久久久久 | 99精品网 | 国产高清视频一区 | 国产一区欧美 |