how to get all parent nodes of given element in pure javascript?

前端 未结 6 2173
执笔经年
执笔经年 2020-12-08 10:01

I mean an array of them. That is a chain from top HTML to destination element including the element itself.

for example for element it would b

相关标签:
6条回答
  • 2020-12-08 10:42

    You can try something like:

    var nodes = [];
    var element = document.getElementById('yourelement');
    nodes.push(element);
    while(element.parentNode) {
        nodes.unshift(element.parentNode);
        element = element.parentNode;
    }
    
    0 讨论(0)
  • 2020-12-08 10:48

    A little shorter (and safer, since target may not be found):

    var a = document.getElementById("target");
    var els = [];
    while (a) {
        els.unshift(a);
        a = a.parentNode;
    }
    
    0 讨论(0)
  • 2020-12-08 10:51

    Something like this:

    var nodeList = [document.getElementById('element')];
    while (nodeList[nodeList.length - 1].parentNode !== document) {
        nodeList.unshift(nodeList[nodeList.length - 1].parentNode);
    }
    
    0 讨论(0)
  • 2020-12-08 10:51

    I believe this will likely be the most performant in the long run in the most scenarios if you are making frequent usage of this function. The reason for why t will be more performant is because it initially checks to see what kind of depths of ancestry it might encounter. Also, instead of creating a new array every time you call it, this function will instead efficiently reuse the same array, and slice it which is very optimized in some browsers. However, since there is no really efficient way I know of to check the maximum depth, I am left with a less efficient query-selector check.

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

    The browser compatibility for the above function is that it will work in Edge, but not in IE. If you want IE support, then you will need a Array.prototype.copyWithin polyfill.

    0 讨论(0)
  • 2020-12-08 10:59

    I like this method:

    [...(function*(e){do { yield e; } while (e = e.parentNode);})($0)]
    

    ... where $0 is your element.

    An upside of this method is that it can be used as a value in expressions.

    0 讨论(0)
  • 2020-12-08 11:04

    Another alternative (based on this):

    for(var e = document.getElementById("target"),p = [];e && e !== document;e = e.parentNode)
    p.push(e);
    
    0 讨论(0)
提交回复
热议问题