19

Possible Duplicate:
Check event.target.parentElement with matchesSelector js

I have a dom object, I'd like to match its parents, all parents, against a selector, like querySelectAll(), but for parents instead of children. Similar to jQuery's .parents('selector') method, but I do NOT need any back-wards compatibility. Also, no libraries please. I will totes take a boolean return value.

I CAN write this myself as a recursive function/for/while using matchesSelector(). I'm looking for little-known methods or more efficient code.

Saving any processing is worth it. Think tens of thousands of match checks, or more even.

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
Randy Hall
  • 7,716
  • 16
  • 73
  • 151
  • 2
    Where is said-code you wrote yourself? (so that people can help point out flaws / add improvements) – Mark Pieszak - Trilon.io Oct 19 '12 at 19:13
  • 1
    This looks like the same issue you asked about earlier: http://stackoverflow.com/questions/12977658/check-event-target-parentelement-with-matchesselector-js – I Hate Lazy Oct 19 '12 at 19:14
  • @user1689607 Ha! Yeah looks that way... I was thinking slightly differently here. I had forgotten about jQuery's parents method. Sigh... been staring at the same code for so long I've forgotten the rest of the world exist... – Randy Hall Oct 19 '12 at 19:17
  • @mcpDESIGNS I said I COULD, not that I have. But I imagine ` for() ` – Randy Hall Oct 19 '12 at 19:19
  • Sorry, can you please expand on why you've marked @MarkPieszak as the correct answer as it doesn't appear to cater for the "upward selector" aspect you are asking for. From what I can make out he is simply returning a selected node's direct family tree. Thanks in advance. – Pancho Jul 28 '16 at 15:03
  • 1
    @Pancho Because he wanted *all* parents UP from a selector. I updated the answer to include an optional 2nd parameter where you can also select where you want it to **stop** adding parents to the Array. :) – Mark Pieszak - Trilon.io Jul 28 '16 at 15:29
  • [`Element::closest`](https://developer.mozilla.org/en-US/docs/Web/API/Element/closest) – Steven Vachon May 02 '19 at 20:49

1 Answers1

43

You would want to use a while() loop since we don't know the exact number of parents we have

jsFiddle Demo

function getParents(el, parentSelector /* optional */) {

    // If no parentSelector defined will bubble up all the way to *document*
    if (parentSelector === undefined) {
        parentSelector = document;
    }

    var parents = [];
    var p = el.parentNode;
    
    while (p !== parentSelector) {
        var o = p;
        parents.push(o);
        p = o.parentNode;
    }
    parents.push(parentSelector); // Push that parentSelector you wanted to stop at
    
    return parents;
}

Useage: Returns an Array of "parents"

// 2nd param optional, bubbles up to document
getParents( document.getElementById('me') ); 

// get all parents starting from -me- up to ID -outerParent-
getParents( document.getElementById('me'), document.getElementById('outerParent') );
Neuron
  • 5,141
  • 5
  • 38
  • 59
Mark Pieszak - Trilon.io
  • 61,391
  • 14
  • 82
  • 96