1

I have a menu that expands and retracts on hover. The problem is the menu has many elements and to trigger my expand function I need to write something like below. My actual code includes more code and I was wondering if there would be a better way to do this.

var e = event.target

if(
e.parentNode.className.split(" ")[0] === "main-section" ||
e.parentNode.parentNode.className.split(" ")[0] === "main-section" ||
e.parentNode.parentNode.parentNode.className.split(" ")[0] === "main-section"){
//do somehtings}

3 Answers3

4

In modern environments you can use the DOM's closest method:

if (e.closest(".main-section")) {
    // One was found...
}

It looks at the current element to see if it matches the selector, then its parent element, then its parent, etc. to the root of the tree. It returns the element it finds, or null if it doesn't find one.

For slightly older environments, Element#closest can be polyfilled. Or if you don't like polyfilling, you can give yourself a utility function instead that uses closest if it exists, or uses matches if not:

function closest(el, selector) {
    if (el.closest) {
        return el.closest(selector);
    }
    var matches = el.matches || el.matchesSelector;
    while (el) {
        if (matches.call(el, selector)) {
            return el;
        }
        el = el.parentNode;
    }
    return null;
}

...which you'd use like this:

if (closest(e, ".main-section")) {
    // One was found...
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

Method closest() is not supported in some browsers, so I took this function for you from this answer

function findAncestor (el, sel) {
    while ((el = el.parentElement) && !((el.matches || el.matchesSelector).call(el,sel)));
    return el;
}
Lab Lab
  • 781
  • 10
  • 34
0

Use classList with a recursive function like so.

const start = document.getElementById("start");

function recursiveCheck(ele, className, limit = 3, current = 0){
   return ele.classList.contains(className) ? true : current >= limit ? false : recursiveCheck(ele.parentNode, className, limit, current + 1);
}

console.log(
  recursiveCheck(start, "test")
);
<div class="test">
  <div>
    <div id="start"><div>
  </div>
</div>
kemicofa ghost
  • 16,349
  • 8
  • 82
  • 131