Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check event.target.parentElement with matchesSelector js

Not concerned about old browser fallback. Also, can't use libraries.

I have an event object. I am testing the event.target against a css selector via matchesSelector:

event['target'].matchesSelector('css selector here');

this works, as does:

event['target']['parentElement'].matchesSelector('css selector here');

...and:

event['target']['parentElement']['parentElement'].matchesSelector('css selector here');

What I'm looking for is some possible object method beyond my understanding that I could use to check each parentElement all the way up for a match, without a for loop. My focus is on efficiency.

Thanks!

like image 315
Randy Hall Avatar asked Dec 05 '22 14:12

Randy Hall


2 Answers

The closest() function will do what you need.

It starts from the element itself, and traverses parents (heading toward the document root) until it finds a node that matches the provided selectorString. Somewhat similar to jQuery's parents() function.

So your code will look like that:

event.target.closest(selectorString)
like image 140
Bassem Avatar answered Dec 28 '22 10:12

Bassem


To prevent redundant looping through all parent elements of your target element, you can perform quick checking for whether your element is inside of an element that matches your selector by using matchesSelector() with selector that is concatenation of your original selector and appended context selector consisting of space and your target-element's tag name:

function getAncestorBySelector(elem, selector) {
    if (!elem.matchesSelector(selector + ' ' + elem.tagName)) {
        // If element is not inside needed element, returning immediately.
        return null;
    }

    // Loop for finding an ancestor element that matches your selector.
}
like image 32
Marat Tanalin Avatar answered Dec 28 '22 09:12

Marat Tanalin