溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript 中怎么利用DOM實現文檔遍歷

發布時間:2021-07-01 15:51:28 來源:億速云 閱讀:383 作者:Leah 欄目:web開發

本篇文章給大家分享的是有關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"> /*  通過ID屬性查找元素 ,用的是文檔對象的getElementById()方法,  查找到我們想要的元素對象,根據這個節點元素的 childNodes 屬性,  遍歷出所有的子節點對象。  */  function queryElementsId(){    var elemensArray,nav,nav_list;    elemensArray=[];    nav=document.getElementById("nav");    /*注意IE和FF中處理Text節點上存在著一些差異*/       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;     }  /*  我們觀察到我的導航條是有規律的,是用無序列表元素組成的,只有定位到 &lt;ul&gt;元素  ;然后把getElementsByTagName()方法可以返回相同元素對象的集合,  查用它找一組元素,太方便了。  */  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"> /*  《精通javascript》上提供了一個函數,用于處理xm中的這些空格,其作用原理就是找出文本節點,并刪除這些節點,以達到刪除這些空格的目的。  */     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">    /*  ***,利用數組寫了一個函數,能夠有效的處理dom中的空格,其原理就是將一個元素的的父元素找出來,然后通過它父元素的childNodes屬性找出該元素的所有兄弟元素。遍歷該元素和它的兄弟元素,將所有元素節點放在一個數組里。這樣調用這個數組,就只有元素節點而沒有文本節點,也就沒有了討厭的空格.     */     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"> /*  原理是對元素的所有的子節點做一個遍歷。然后做一個判斷,如果是子元素節點(nodeType = 1),則遍歷該子元素的所有的子節點,用遞歸檢查是否包含空白節點;如果處理的子節點是文本節點(nodeType = 3),則檢查是否是純粹的空白節點,如果是,就將它從xml對象中刪除。  */  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");    /*處理#Text節點問題*/    removeWhitespace(nav);       /*注意IE和FF中處理Text節點上存在著一些差異*/       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);       /*處理FF遍歷節點中的#Text */    removeWhitespace(nav);//移除所有的空Text節點       /*查找子節點*/      var c_n_f=nav.firstChild;//***個節點對象    //var c_n_f=nav.childNodes[0];//同上一樣的結果    var c_n_l=nav.lastChild;//***一個節點對象    //var c_n_l=nav.childNodes[nav.childNodes.length-1];//同上一樣的結果    alert("***個節點:"+c_n_f.nodeName+"  "+"***一個節點 :"+c_n_l.nodeName);     /*查找兄弟節點 或叫 相鄰節點 */    /*用nextSibling和PreviousSibling必須有一個參考點,這樣指針才知道自己往那里移動*/    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實現文檔遍歷,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女