2012-10-30 45 views
1

請不要使用庫解決方案,但如果您知道某個解決方案,請高興看看它們是如何做到的。不太擔心後備和跨瀏覽器支持。獲取目標元素的(數字)dom層次結構javascript

我有一個層次結構(這將改變):

<body> 
    <div></div> 
    <div> 
     <div></div> 
     <div></div> 
     <div> 
      <a>Click Me!</a> 
     </div> 
    </div> 
</body> 

我有<a>Click Me!</a>事件偵聽器,並得到一個事件對象返回。這很有效。 YEY!

我想要event.target dom層次數字索引。基本上,[0][1][2][0](雖然它可能會返回爲一個數組,[0,1,2,0],這對我來說沒關係)。

我知道這可以通過迭代父元素來完成。我試圖避免該迭代,如果可能的話。

編輯 編輯我的最後編輯爲白癡行爲。

+2

嗯,你怎麼來計算,包括父母的位置元素的位置,如果你*不*遍歷家長?我不確定這是可能的。 –

+0

我也不確定,我希望有一些*神奇的方式來做到這一點。也許把DOM看作一個數組,並得到'event.target'的索引?這些複雜性超出了我對javascript =) –

+0

的理解。也許是另一種看待這個問題的方法:元素是否知道它在dom中的深處位置,並且可以被訪問? –

回答

5

獲取索引而不顯式迭代的方法是使用數組indexOf方法。

這是它會是什麼樣子,E爲您的活動:

function getIndex(e){ 
    var t=e.target; 
    return Array.prototype.indexOf.call(t.parentNode.childNodes,t); 
} 

有許多使用該技術的陷阱中。首先,indexOf只支持最新的瀏覽器。其次,您需要調用技巧,因爲NodeList不是數組。第三,childNodes可能會返回比預期更多的節點,然後您必須按節點類型進行過濾。

爲了獲得整個層次結構索引,只需在使用parentNode爬上DOM層次結構時重複一遍。

爲了記錄,e.target也不是跨瀏覽器,但我看到這是你已經使用。

[更新]完整的代碼,利用兒童代替的childNodes:

function getIndex(e) { 
var index=[], 
    t=e.target; 

while (t!==document.body) { 
    index.unshift(Array.prototype.indexOf.call(t.parentElement.children,t)); 
    t=t.parentElement; 
} 
return index; 
} 
+0

可以使用't.parentElement.children'作爲第一個參數,應該只返回元素,而不是節點。至少,這就是事件目標在Chrome中的佈局。 –

+0

@RandyHall的權利,在這裏,你將不得不考慮瀏覽器支持「兒童」。 – Christophe

+0

是真的......我得看看它。我主要關心的是'現代'瀏覽器(主要是移動設備)。 –

3

我知道你想避免重複,但它可能是最直接的策略:

$(document).on('click','a', function(e){ 
    var result=[]; 
    var count = function(e){ 
    if(e.parentNode != document.body){ 
     result.push(e); 
     count(e.parentNode); 
    }else { 
     return result;          
    } 
}; 
count(e.target) 
console.log(result); 
}); 

爲了什麼原因,你想避免重複? dom是巨大的還是什麼?

+0

在移動環境中,潛在的巨大活動被稱爲經常發生的事情。「<正在研究我瘋狂創意的可能性。 –

+0

請使用迭代*或*遞歸,但不要混合它們。迭代(沒有函數調用)會更快,順便說一句 – Bergi

+0

您的最終條件是有缺陷的。可能有節點會收到一個點擊事件,但在他們的祖先中沒有'document.body' – Bergi

1

你說「元素會在網頁上動態地改變」,並且你「試圖在JavaScript中創建一個模擬DOM中元素位置的數組」。這意味着您不僅需要重新計算移動元素的索引路徑,還需要重新計算的索引路徑,這些路徑不會移動。底線:不是計算單個元素的路徑,而是重複遍歷整個層次結構,因爲無論如何,您需要重新計算一次,而不是所有索引路徑。

+0

當我向dom添加新元素時,如果我知道索引路徑,我可以將它們切分爲全等數組。 –

+0

@RandyHall我明白了。你並不關心索引路徑,它只是一箇中間計算步驟。 – Christophe

+0

獎金問題:當從DOM中刪除節點時,您打算如何繼續? – Christophe