检查类是否存在于父级 - vanilla JS中

时间:2013-05-31 18:50:11

标签: javascript dom

我真的很难看到如何做到这一点。我想检查一个类是否存在于元素的一个父元素中的某个位置。

我不想使用任何库,只需使用vanilla JS。

在下面的示例中,如果有问题的元素位于元素的子节点中,并且“the-class”作为类名,则它应该返回true。

我认为jQuery会是这样的:

if( $('#the-element').parents().hasClass('the-class') ) {
    return true;
}

所以这返回true:

<div>
    <div class="the-class">
        <div id="the-element"></div>
    </div>
</div>

这样做:

<div class="the-class">
    <div>
        <div id="the-element"></div>
    </div>
</div>

...但这会返回false:

<div>
    <div class="the-class">
    </div>
    <div id="the-element"></div>
</div>

9 个答案:

答案 0 :(得分:32)

你必须递归地执行:

// returns true if the element or one of its parents has the class classname
function hasSomeParentTheClass(element, classname) {
    if (element.className.split(' ').indexOf(classname)>=0) return true;
    return element.parentNode && hasSomeParentTheClass(element.parentNode, classname);
}

Demonstration(打开控制台查看true

答案 1 :(得分:6)

fiddle

代码

function hasClass(element, className) {
  var regex = new RegExp('\\b' + className + '\\b');
  do {
    if (regex.exec(element.className)) {
      return true;
    }
    element = element.parentNode;
  } while (element);
  return false;
}

OR

function hasClass(element, className) {
  do {
    if (element.classList && element.classList.contains(className)) {
      return true;
    }
    element = element.parentNode;
  } while (element);
  return false;
}

答案 2 :(得分:3)

我对Denys Séguret发布的功能感到满意,看起来很优雅,我喜欢它。 我只是稍微调整了一下这个函数,因为如果参数中指定的类不存在于整个DOM中,它会在递归到达文档对象时失败,因为我们控制该元素是否具有父节点(在最后一行,当文档是父节点为空的元素时)但在我们执行上一行之前,当元素是文档时,document.classNameundefined并且它失败,所以控件必须移到顶部。

function hasSomeParentTheClass(element, classname) {
    //
    // If we are here we didn't find the searched class in any parents node
    //
    if (!element.parentNode) return false;
    //
    // If the current node has the class return true, otherwise we will search
    // it in the parent node
    //
    if (element.className.split(' ').indexOf(classname)>=0) return true;
    return hasSomeParentTheClass(element.parentNode, classname);
}

答案 3 :(得分:2)

我相信if( $('#the-element').parents('.the-class').length )更有效率,但也许不像人类可读;其中,图片中querySelector可以用以下方法替换:

function hasParent(element, parentSelector) {
    var potentialParents = document.querySelectorAll(parentSelector);
    for(i in potentialParents) if(potentialParents[i].contains(element))
        return potentialParents[i];
    return false;
}

这会让你有能力:

var elm = document.getElementById('the-element');
if(hasParent(elm, '.the-class')) return true;

答案 4 :(得分:1)

对于那些喜欢这种样式的现代/多填充浏览器的人来说,是另一种选择。

const hasClass = (element, className) => {
    return element.classList.contains(className);
};

const hasParent = (element, className) => {
    if (!element.parentNode) {
        return false;
    }

    if (hasClass(element, className)) {
        return true;
    }

    return hasParent(element.parentNode, className)
};

工作演示:

const hasClass = (element, className) => {
    return element.classList.contains(className);
};

const hasParent = (element, className) => {
    if (!element.parentNode) {
        return false;
    }

    if (hasClass(element, className)) {
        return true;
    }

    return hasParent(element.parentNode, className)
};


/* Demo Code, can ignore */
const child = document.getElementById('child');
const orphan = document.getElementById('orphan');
const output = document.getElementById('output');

const log = `child has parent? ${hasParent(child, 'list')}
orphan has parent? ${hasParent(orphan, 'list')}
`

output.innerText = log;
#output {
  margin-top: 50px;
  background: black;
  color: red;
  padding: 20px;
}
<div>
  <ul class="list">
    <li>
      <a id="child" href="#">i have a parent</a> 
    </li>
  </ul>
</div>

<div>
  <ul>
    <li>
      <a id="orphan" href="#">im an orphan</a> 
    </li>
  </ul>
</div>

<div id="output"></div>

答案 5 :(得分:1)

尝试使用 closest() 函数-对于集合中的每个元素,通过测试元素本身并遍历DOM树中的祖先,获得与选择器匹配的第一个元素。请在此处参考Official Docs

答案 6 :(得分:0)

我对Vanilla JS的例子,它使用来自jQuery的parents()的vanilla

var htmlElement = <htmlElement>,
    parents = [],
    classExist;
while (htmlElement = htmlElement.parentNode.closest(<parentSelector>)) {
    parents.push(htmlElement);
}
classExist = (parents > 0);

所以你的选择器只是.className

并检查父母是否&gt; 0

答案 7 :(得分:0)

您可以使用closest()的{​​{1}}方法来遍历Element的父项(朝向文档根目录),直到找到与所提供的selectorString匹配的节点为止。将返回自己或匹配的祖先。如果不存在这样的元素,则返回null。

您可以将返回值转换为布尔值

Element
const el = document.getElementById('div-03');

const r1 = el.closest("#div-02");  
console.log(Boolean(r1));
// returns the element with the id=div-02

const r2 = el.closest("#div-not-exists");
console.log(Boolean(r2));

答案 8 :(得分:-1)

因为ID在文档上下文中必须是唯一的,所以您可以改为使用:

return !!document.querySelector('.the-class #the-element');

如果要包含元素本身,可以使用:

return !!document.querySelector('.the-class #the-element, #the-element.the-class');