检查父节点之一是否具有特定类的优雅方法

时间:2019-03-17 12:40:52

标签: javascript html

我有一个菜单,可以在悬停时扩展和收缩。问题是菜单包含许多元素,要触发我的扩展功能,我需要编写以下内容。我的实际代码包含更多代码,我想知道是否有更好的方法可以做到这一点。

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 个答案:

答案 0 :(得分:4)

在现代环境中,您可以使用DOM的closest方法:

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

它查看当前元素,以查看它是否与选择器匹配,然后与它的父元素匹配,然后与它的父元素匹配,然后与树的根匹配。它返回找到的元素,如果找不到则返回null

对于稍旧的环境,可以进行Element#closest的填充。或者,如果您不喜欢polyfilling,则可以给自己一个实用函数,如果存在,则使用closest,否则使用matches

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;
}

...您将这样使用:

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

答案 1 :(得分:0)

某些浏览器不支持方法closest(),因此我从此answer

开始使用了此功能。
function findAncestor (el, sel) {
    while ((el = el.parentElement) && !((el.matches || el.matchesSelector).call(el,sel)));
    return el;
}

答案 2 :(得分:0)

classList与递归函数一起使用。

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>