Javascript 检查类是否存在于parent-JS中的某个位置

Javascript 检查类是否存在于parent-JS中的某个位置,javascript,dom,Javascript,Dom,我真的很想知道怎么做。我想检查一个类是否存在于某个元素的某个父元素中 我不想使用任何库,只想使用vanilla JS 在下面的示例中,如果所讨论的元素位于以“类”作为类名的元素的子元素中的某个位置,则应返回true 我认为jQuery应该是这样的: if( $('#the-element').parents().hasClass('the-class') ) { return true; } 所以这是真的: <div> <div class="the-clas

我真的很想知道怎么做。我想检查一个类是否存在于某个元素的某个父元素中

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

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

我认为jQuery应该是这样的:

if( $('#the-element').parents().hasClass('the-class') ) {
    return 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>

您必须递归地执行此操作:

// 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);
}
(打开控制台以查看
true

代码

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

我认为
if($('#元素').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;

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

return !!document.querySelector('.the-class #the-element');
如果要包含元素本身,可以使用:

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

我的示例是Vanilla JS,它使用jQuery中的
parents()
的Vanilla等价物

var htmlElement = <htmlElement>,
    parents = [],
    classExist;
while (htmlElement = htmlElement.parentNode.closest(<parentSelector>)) {
    parents.push(htmlElement);
}
classExist = (parents > 0);
var htmlElement=,
父母=[],
阶级存在;
while(htmlElement=htmlElement.parentNode.closest()){
家长推送(htmlElement);
}
classExist=(父项>0);
因此,您的选择器只是一个
.className


只需检查parent是否大于0,我对发布的函数没意见,它看起来很优雅,我很喜欢。 我只是稍微调整了一下这个函数,因为如果参数中指定的类不存在于整个DOM中,那么当递归到达document对象时,它会失败,因为我们控制元素是否有父节点(在最后一行中,当document是元素时,父节点为null)但是在执行前一行之前,当元素是document时,
document.className
undefined
,它失败了,因此必须将控件移到顶部

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

您可以使用
some
contains
来实现以下结果:

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

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

可以使用
Element
closest()。将返回自身或匹配的祖先。如果不存在这样的元素,则返回null

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

const el=document.getElementById('div-03');
常数r1=最近标高(#div-02”);
log(布尔值(r1));
//返回id为div-02的元素
常数r2=el.最近(#div不存在);
log(布尔值(r2))

这是div-01
这是02组
这是03组

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

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=(元素,类名)=>{
return元素.classList.contains(className);
};
const hasParent=(元素,类名)=>{
如果(!element.parentNode){
返回false;
}
if(hasClass(元素,类名)){
返回true;
}
return hasParent(element.parentNode,className)
};
/*演示代码,可以忽略*/
const child=document.getElementById('child');
const-orphan=document.getElementById('orphan');
const output=document.getElementById('output');
const log=`子级有父级吗${hasParent(child,'list')}
孤儿有父母吗${hasParent(孤立,'list')}
`
output.innerText=log
#输出{
边缘顶部:50px;
背景:黑色;
颜色:红色;
填充:20px;
}


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

使用jquery,这将是最接近的(“.theclass”)。长度您是否有任何代码来显示您所尝试的内容,以便我们可以看到您可能需要帮助的地方?因此,您想看看是否有任何祖先或祖先的兄弟姐妹具有给定的类名?我遇到了相同的问题,并提出了此解决方案,所以我想我应该把它贴在这里,让其他面临这个问题的人知道。为什么$efficent更有效?@SuperUberDuper我并不是说jQuery比单一用途的普通代码更有效,如果你是这么问的话。我的意思是,我认为,与OP的jq行相比,使用带有父母的选择器可能会减少一个循环。糟糕的措辞,嗯?这是一个很好的方法。我只建议运行.hasOwnProperty()检查。如果som父级没有未定义的classcannot split,则检查失败。我使用此代码处理没有类的元素:
var hassomeParentClass=function(element,classname){if(element.classname&&element.classname.split('').indexOf(classname)>=0)return true;return element.parentNode&&hasSomeParentTheClass(element.parentNode,classname);}
使用
parentElement
而不是
parentNode
可以避免这个问题。@lexa IE9不知道什么是类列表。这真是聪明。。只需要修复,因为
el.contains(el)返回true
。因此,我们应该将其重写为:
el!==target&&el.contains(target)
不需要单独的条件,您可以通过执行显式空检查来确保获得布尔值:
element.parentNode!=null&&hassomeparentheclass(..)
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)
};