Reputation: 458
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}
Upvotes: 1
Views: 48
Reputation: 17606
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>
Upvotes: 0
Reputation: 801
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;
}
Upvotes: 0
Reputation: 1074068
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...
}
Upvotes: 5