2013-08-21 50 views
3

例如:如何遍歷DOM以確定最大嵌套深度?

// ... 
<body> 
    <div> 
    <div> 
    </div> 
    </div> 
</body> 
// ... 

這窩深度將是3?但更一般地說,我如何遍歷DOM來找到這些信息?

我感興趣的處理DOM像建模爲一個對象在這篇文章中描述文字的n元樹:

n-ary tree in JavaScript

+0

既然你不搜索特定的東西,或適用的任何算法樹的一部分,這有什麼錯一個簡單的有序[全]樹遍歷? – Bergi

+0

這很好,我將如何實現最好? –

+0

遞歸是最簡單的。去嘗試一下! – Bergi

回答

1

如果唯一的目的是確定最大嵌套級別,我會考慮使用querySelector(因爲它應該是很好的優化):

function getMaxNestLevel() { 
    var i = 1, sel = '* > *'; /* html > body is always present */ 
    while(document.querySelector(sel)) { 
     sel += ' > *'; 
     i++; 
    } 
    return i; 
} 

Example(本SO頁面標記的一部分)

+0

我敢打賭,這比某些形式的DOM行走慢得多。當然,只有測試才能說明問題。 –

+0

@CrazyTrain,如果DOM變得非常大,嵌套級別超過30(http://jsfiddle.net/BBtYg/3/),那麼你是對的,它會變得更慢(與joellustigman的解決方案相比)。但對於相對平坦的DOM,嵌套級別大約爲20,在Firefox和IE11中似乎要快一些(http://jsfiddle.net/BBtYg/2/)。 –

+0

@瘋狂 - 我提名你寫jsperf! –

1

我個人最喜歡的是使用堆棧。您不斷推送標籤,直到您達到相應的/對稱的結束標籤。然後你可以彈出或做你想要的任何分析。這是Comp Sci Data Structures類的一個典型例子。

+0

除此之外...繼續推/彈出並保持變量中已達到的最大堆棧大小。在最後一個流行音樂之後,您有深度。 +1的答案。 – Renan

+2

這是DOM,而不是HTML標記。 「匹配標籤」不需要堆疊。 – Bergi

+0

你是對的,Bergi。我從另一個角度看待它。 – eatonphil

3
function getMaximumDepth (element) { 
    var child = element.firstChild; 
    var childrenDepth = []; 

    if (! child) { 
     return 1; 
    } 

    while (child) { 
     childrenDepth.push(getMaximumDepth(child)); 
     child = child.nextSibling; 
    } 

    return Math.max.apply(Math, childrenDepth) + 1; 
} 

演示:http://jsfiddle.net/53R2p/

3

一個優雅的遞歸解決方案

使用此功能作爲 - height(document.body)

function height(el) { 
    if (!el.children) 
     return 0; 
    var max = -1; 
    for (var i = 0; i < el.children.length; i++) { 
     var h = height(el.children[i]); 
     if (h > max) { 
      max = h; 
     } 
    } 
    return max + 1; 
}