Как получить все родительские узлы данного элемента в чистом JavaScript? - PullRequest
20 голосов
/ 04 января 2012

Я имею в виду их массив. Это цепочка от верхнего HTML до целевого элемента, включая сам элемент.

например для элемента <A> это будет:

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

Ответы [ 5 ]

35 голосов
/ 04 января 2012

Немного короче (и безопаснее, поскольку target не может быть найдено):

var a = document.getElementById("target");
var els = [];
while (a) {
    els.unshift(a);
    a = a.parentNode;
}
19 голосов
/ 04 января 2012

Вы можете попробовать что-то вроде:

var nodes = [];
var element = document.getElementById('yourelement');
nodes.push(element);
while(element.parentNode) {
    nodes.unshift(element.parentNode);
    element = element.parentNode;
}
3 голосов
/ 04 января 2012

Примерно так:

var nodeList = [document.getElementById('element')];
while (nodeList[nodeList.length - 1].parentNode !== document) {
    nodeList.unshift(nodeList[nodeList.length - 1].parentNode);
}
1 голос
/ 01 июля 2018

Другая альтернатива (на основе this ):

for(var e = document.getElementById("target"),p = [];e && e !== document;e = e.parentNode)
p.push(e);
0 голосов
/ 08 сентября 2017

Я полагаю, что это будет наиболее эффективным в долгосрочной перспективе в большинстве сценариев, если вы часто используете эту функцию. Причина, по которой t будет более производительным, заключается в том, что он первоначально проверяет, с какой глубиной предков он может столкнуться. Кроме того, вместо создания нового массива каждый раз, когда вы вызываете его, эта функция вместо этого будет эффективно повторно использовать тот же массив и нарезать его, что очень оптимизировано в некоторых браузерах. Однако, поскольку я не знаю действительно эффективного способа проверить максимальную глубину, у меня осталась менее эффективная проверка выбора запроса.

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

Совместимость браузера для вышеуказанной функции заключается в том, что она будет работать в Edge, но не в IE. Если вам нужна поддержка IE, вам понадобится Array.prototype.copyWithin polyfill.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...