2012-01-04 13 views

risposta

30

Un po 'più breve (e più sicuro, dal momento che target potrebbero non essere ritrovate):

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

Ho cambiato risposta accettata. Questo è il più elegante. (btw, I test dimostrano che push and then reverse è più efficiente.) [Vorrei che ci fosse un'opzione per accettare più di una risposta, anche al costo dei miei punti.] – rsk82

+0

Questo includerà il nodo del documento. Se desideri fermarti all'elemento 'HTML', modifica 'a = a.parentNode' a' a = a.parentElement' –

16

si può provare qualcosa di simile:

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

Ah, bastonatemi. +1 –

+4

+1. batto anche a me, ma invece di usare 'reverse()' alla fine, userei semplicemente 'unshift()' invece di 'push()' –

+0

Sì, invece di usare il reverse alla fine, usare unshift sarebbe essere un modo più efficace di farlo. Risposta modificata. – techfoobar

3

Qualcosa del genere:

var nodeList = [document.getElementById('element')]; 
while (nodeList[nodeList.length - 1].parentNode !== document) { 
    nodeList.unshift(nodeList[nodeList.length - 1].parentNode); 
} 
0

Credo che questa sarà probabilmente la più performante nel lungo periodo nelle maggior parte degli scenari se si stanno facendo uso frequente di questa funzione. Il motivo per cui t sarà più performante è perché inizialmente controlla per vedere quale tipo di profondità di discendenza potrebbe incontrare. Inoltre, invece di creare un nuovo array ogni volta che lo chiami, questa funzione riutilizzerà in modo efficiente lo stesso array e lo traccerà, che è molto ottimizzato in alcuni browser. Tuttavia, poiché non conosco un modo veramente efficace per verificare la profondità massima, mi rimane un controllo meno efficiente della selezione delle query.

// !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) 
} 

La compatibilità del browser per la funzione precedente è che funzionerà in Edge, ma non in IE. Se si desidera il supporto IE, sarà necessario un polyfill Array.prototype.copyWithin.

Problemi correlati