【翻譯作品】JavaScript DOM學習第四章:getElementByTagNames

來源:互聯網
上載者:User
文章目錄
  • 執行個體1
  • 執行個體2
  • 背景:array.sort()
  • sourceIndex
  • compareDocumentPosition

HTML有一些相關有不同tag名字的相關元素,比如H1-H6或者input,select和TEXTAREA。getElementByTagName只能取得那些有相同tag名稱的元素,所以你不能用他來取得所有的標題或者整個表單內容。

getElementByTagNames(注意是複數的names)會獲得一些tag的元素,然後按照他們的順序儲存在一個數組中。這非常的有用,比如在上一章的TOCScript中,就需要獲得整個文章裡面的所有的H3和H4。

我非常希望在node原型中加入這個功能,但是在IE和Safari裡面不行。所以只能把他當做一個普通函數。

 

使用

getElementByTagNames有兩個參數:

1、一個用逗號分隔的tag名稱字串。

2、一個可選的開始元素。如果存在則在該元素的子項目中尋找這些tag,如果不存在則在整個文檔中尋找。

這個函數根據要求的tag名稱返回一個數組(而不是節點列表),按照他們在原始碼中的出現順序排列。對於這個排序需要瀏覽器支援sourceIndex或者compareDocumentPosition。如果都不支援(Safari)那麼就按照調用getElementByTagNames()函數時候的tag名稱的順序。

執行個體1
var headerList = getElementsByTagNames('h1,h2,h3,h4');

現在headerList就是文檔裡包含H1-H4的數組,按照他們出現的順序排序。

執行個體2
var element = document.getElementById('test');var formFieldList = getElementsByTagNames('input,select,textarea',element);

現在formFieldList就是包含在ID為test的元素下的所有子項目中的input,select,TEXTAREA的數組,並且按照他們出現的書序排列。

 

代碼
function getElementsByTagNames(list,obj) {if (!obj) var obj = document;var tagNames = list.split(',');var resultArray = new Array();for (var i=0;i<tagNames.length;i++) {var tags = obj.getElementsByTagName(tagNames[i]);for (var j=0;j<tags.length;j++) {resultArray.push(tags[j]);}}var testNode = resultArray[0];if (!testNode) return [];if (testNode.sourceIndex) {resultArray.sort(function (a,b) {return a.sourceIndex - b.sourceIndex;});}else if (testNode.compareDocumentPosition) {resultArray.sort(function (a,b) {return 3 - (a.compareDocumentPosition(b) & 6);});}return resultArray;}

 

 

解釋
function getElementsByTagNames(list,obj){if (!obj) var obj = document;

首先定義開始元素obj,如果沒有給出,那麼預設就是document。

var tagNames = list.split(',');var resultArray = new Array();

將這些tag名稱以逗號分割。用一個數組來儲存結果。

for (var i=0;i<tagNames.length;i++) {var tags = obj.getElementsByTagName(tagNames[i]);for (var j=0;j<tags.length;j++) {resultArray.push(tags[j]);}}

現在我們遍曆所有的tag名稱,就用最簡單的getElementByTagName()方法,然後把結果傳入resultArray。這裡的一個要點是,因為getElementByTagName返回的是節點列表,所以我就不能使用array.concat()來建立新的數組。把元素一個一個的壓入是我能找到的最好的辦法。

我們得到了一個所需的tag名稱的元素的指標數組儲存在resultArray中,但是這些元素還是按照我們所給的tag的順序排列的。我們需要再排個序。

var testNode = resultArray[0];

現在我們開始排序。我們需要知道瀏覽器是否支援sourceIndex或者compareDocumentPosition,然後我們對於我們的得到的未經處理資料做一些檢測

if (!testNode) return [];

如果這裡沒有第一個節點(也就是說結果裡並沒有我們需要的元素),就返回一個空數組。

 

背景:array.sort()

array.sort()方法有一個可選函數的參數。這個函數用來比較兩個元素(通常稱為a和b)。如果第一個應該在前那麼這個函數就返回一個負數,如果第二個應該在前那麼就返回一個正值。

sourceIndex

如果瀏覽器支援sourceIndex,我們就根據元素的sourceIndex來排序。sourceIndex是微軟的一個非常有用的擴充,可以用來知道元素在原始碼中的索引值。頁面種的第一個元素(<HTML>)的索引值就是0,第二個(<head>)就是1,等等。sourceIndex也是getElementByTagName(*)中的元素的索引值。

if (testNode.sourceIndex) {resultArray.sort(function (a,b) {return a.sourceIndex - b.sourceIndex;});}

我們用第一個元素的sourceIndex值減去第二個元素的sourceIndex,如果是負值,那麼第一個元素就排在前面,如果是正值,那麼第二個元素排在前面。這就是sort()需要的。現在resultArray中的元素就是根據他們在文檔中的位置來排序的。

compareDocumentPosition

如果瀏覽器支援compareDocumentPosition,那麼就用這個辦法來排序。compareDocumentPosition是level3的核心方法,他可以比較兩個節點在文檔中的位置,然後返回一個值:

1 沒有找到

2 在前

4 在後

8 包含

16 被包含

比如,如果一個標籤被包含並且在另一個標籤的後面,那麼就返回16+4=20。

else if (testNode.compareDocumentPosition) {resultArray.sort(function (a,b) {return 3 - (a.compareDocumentPosition(b) & 6);});}

我們只對compareDocumentPosition的值中的2、4感興趣:在前或者在後。所以我們將結果和6進行與運算,這樣結果就會是2或者4(當然結果不能是6,因為一個元素不能即在一個元素之前又在一個元素之後)

如果b在a之後則返回4,但是sort()需要一個負數。如果b在a之前則返回2,但是sort()需要一個正數。為了給sort()一個正確的結果我把他們用3來減。這樣就得到1或者-1,這樣sort()就能對元素進行正確的排序,resultArray中的元素也按照他們在文檔種的出現順序排列。

return resultArray;}

然後我們返回resultArray給調用它的函數。記住如果瀏覽器不支援sourceIndex或者compareDocumentPosition數組就沒有排序。

 

翻譯地址:http://www.quirksmode.org/dom/getElementsByTagNames.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.