2012-01-04 16 views
17

Onlardan bir dizi demek istiyorum. Bu, öğenin kendisi de dahil olmak üzere, üst HTML'den hedef öğeye bir zincirdir.Belirli öğelerin tüm ana düğümlerini saf javascript'e nasıl alabilirsiniz?

eleman <A> örneğin olurdu: (target bulunamayabilir beri ve daha güvenli)

var nodes = []; 
var element = document.getElementById('yourelement'); 
nodes.push(element); 
while(element.parentNode) { 
    nodes.unshift(element.parentNode); 
    element = element.parentNode; 
} 

cevap

30

Biraz daha kısa:

[HTML, BODY, DIV, DIV, P, SPAN, A] 
+5

Kabul edilen cevabı değiştirdim. Bu en zarif olanı. (btw, testler, itme ve daha sonra tersinin daha verimli olduğunu gösterir.) [Keşke puanlarımın maliyetinde bile birden fazla cevabı kabul etme seçeneği olsaydı.] – rsk82

+0

Bu, belge düğümünü içerecektir. 'HTML' öğesinde durdurmak isterseniz, 'a = a.parentNode' ifadesini 'a = a.parentElement' olarak değiştirin. –

16

Sen gibi bir şey deneyebilirsiniz

var a = document.getElementById("target"); 
var els = []; 
while (a) { 
    els.unshift(a); 
    a = a.parentNode; 
} 
+1

Ah, bana onu döv. +1 –

+4

+1. bana da onu döverim, ama yerine 'reverse()' yerine, sadece 'unshift()' 'push()' yerine –

+0

kullanın. Bunu yapmanın daha etkili bir yolu ol. Cevap düzenlendi. – techfoobar

3

Böyle bir şey:

var nodeList = [document.getElementById('element')]; 
while (nodeList[nodeList.length - 1].parentNode !== document) { 
    nodeList.unshift(nodeList[nodeList.length - 1].parentNode); 
} 
0
Sana bu fonksiyonun sık kullanım yapıyoruz Bunun büyük olasılıkla en senaryolarda uzun vadede yılında etkili ve verimli olacağına inanıyoruz. Neden daha fazla performansa sahip olacağının nedeni, başlangıçta ne tür derinliklerin karşılaşabileceğini görmeyi kontrol etmesidir. Ayrıca, her arama yaptığınızda yeni bir dizi oluşturmak yerine, bu işlev aynı diziyi verimli bir şekilde yeniden kullanacak ve bazı tarayıcılarda çok iyi bir şekilde optimize edilen bir dilimle dilimleyecektir. Ancak, maksimum derinliği kontrol etmek için bildiğim kadar etkili bir yöntem olmadığından, daha az etkili bir sorgu seçici kontrolüyle kaldım.
// !IMPORTANT! When moving this coding snippet over to your production code, 
// do not run the following depthtest more than once, it is not very performant 
var kCurSelector="*|*", curDepth=3; 
while (document.body.querySelector(kCurSelector += '>*|*')) curDepth++; 
curDepth = Math.pow(2, Math.ceil(Math.log2(startDepth))), 
var parentsTMP = new Array(curDepth); 

function getAllParentNodes(Ele){ 
    var curPos = curDepth; 

    if (Ele instanceof Node) 
     while (Ele !== document){ 
     if (curPos === 0){ 
      curPos += curDepth; 
      parentsTMP.length <<= 1; 
      parentsTMP.copyWithin(curDepth, 0, curDepth); 
      curDepth <<= 1; 
     } 
     parentsTMP[--curPos] = Ele; 
     Ele = Ele.parentNode; 
     } 
    return retArray.slice(curPos) 
} 

Yukarıdaki işlevin tarayıcı uyumluluğu, Edge'de çalışacağı, ancak IE'de çalışmadığıdır. IE desteğini istiyorsanız, bir Array.prototype.copyWithin polyfill'e ihtiyacınız olacaktır.

İlgili konular