javascript 检查类是否存在于父级中的某处 - vanilla JS

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16863917/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 06:16:58  来源:igfitidea点击:

Check if class exists somewhere in parent - vanilla JS

javascriptdom

提问by user2143356

I'm really struggling to see how to do this. I want to check if a class exsits somewhere in one of the parent elements of an element.

我真的很想知道如何做到这一点。我想检查一个类是否存在于某个元素的父元素之一中。

I don't want to use any library, just vanilla JS.

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

In the examples below it should return true if the element in question resides somewhere in the childs of an element with "the-class" as the class name.

在下面的示例中,如果所讨论的元素位于以“the-class”作为类名的元素的子元素中的某个位置,则它应该返回 true。

I think it would be something like this with jQuery:

我认为jQuery会是这样的:

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

So this returns true:

所以这返回真:

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

So does this:

这样做也是如此:

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

...but this returns false:

...但这返回错误:

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

回答by Denys Séguret

You'll have to do it recursively :

你必须递归地做:

// 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(open the console to see true)

演示(打开控制台查看true

回答by James Newton

The fiddle

小提琴

The code

代码

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

回答by Fez Vrasta

You can use someand containsto achieve the result:

您可以使用somecontains来实现结果:

function hasParentWithMatchingSelector (target, selector) {
  return [...document.querySelectorAll(selector)].some(el =>
    el !== target && el.contains(target)
  )
}

// usage
hasParentWithMatchingSelector(myElement, '.some-class-name');

回答by AndreaScn

I'm ok with the function that Denys Séguretposted, it looks elegant and I like it. I just tweaked a little bit that function since if the class specified in the parameter, is not present in the whole DOM, it fails when the recursion reaches the document object because is true that we control if the element has the parent node (in the last line, and when the document is the element the parent node is null) but before we execute the previous line, and when the element is the document, document.classNameis undefinedand it fails, so the control must be moved to the top.

我对Denys Séguret发布的功能感到满意,它看起来很优雅,我喜欢它。我只是稍微调整了这个函数,因为如果参数中指定的类不存在于整个 DOM 中,当递归到达文档对象时它会失败,因为我们控制元素是否具有父节点(在最后一行,当文档是元素的父节点为null)但在此之前,我们执行前行,当元素是文件,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);
}

回答by a.robert

You can use the closest()method of Elementthat traverses parents (heading toward the document root) of the Element until it finds a node that matches the provided selectorString. Will return itself or the matching ancestor. If no such element exists, it returns null.

您可以使用closest()的方法Element,直到找到所提供的selectorString匹配的节点的元素的横穿父母(朝文档根目录标题)。将返回自身或匹配的祖先。如果不存在这样的元素,则返回 null。

You can convert the returned value into boolean

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

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));
<article>
  <div id="div-01">Here is div-01
    <div id="div-02">Here is div-02
      <div id="div-03">Here is div-03</div>
    </div>
  </div>
</article>

回答by Fardin K.

I believe if( $('#the-element').parents('.the-class').length )to be more efficient, but perhaps not as human-readable; which, with querySelectorin the picture, could be replaced with the following method:

我相信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;
}

That'd give you the ability to do:

这将使您能够执行以下操作:

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

回答by Owen

Another alternative for some those who like this style for modern/polyfilled browsers.

对于那些喜欢这种风格的现代/polyfill 浏览器的人来说,这是另一种选择。

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


Working demo:

工作演示:

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>

回答by bryanxkier

Try the closest()function - For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. Refer to the Official Docshere.

尝试closest()函数 - 对于集合中的每个元素,通过测试元素本身并在 DOM 树中向上遍历其祖先来获取与选择器匹配的第一个元素。请参阅此处的官方文档

回答by Bruno Lesieur

My example for Vanilla JS, it's use a vanilla equivalent of parents()from jQuery

我的 Vanilla JS 示例,它使用了相当于parents()jQuery的 vanilla

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

So your selector just to be a .className

所以你的选择器只是一个 .className

And just check if parent is > 0

只需检查父母是否> 0

回答by A. Wolff

Because ID must be unique on document context, you could just use instead:

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

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

If you want to include element itself, you can use:

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

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