18

我有一个代码,其中包含许多共享相同类名的子菜单。

这是一个结构:

.menu
  .sub-menu
  .sub-menu
    .sub-menu
    .sub-menu
  .sub-menu
    .sub-menu
      .elem
      .elem
  .sub-menu

请注意,.sub-menu深度可能是无限的。

那么我如何实现这一点:.elem单击时,我想向上遍历 DOM 直到.sub-menu到达最顶部并对其应用样式。我知道.closest()and .parent().find()但我不知道 jQuery 是否有这样的功能,例如.topMost(selector)

我能想到的唯一方法可能是运行一个循环并遍历.closest('.sub-menu')新元素,直到它的长度为零(这个类没有更多的父级,所以它必须是最顶层的)。但是,我认为应该有一个更实际的方法来解决这个问题。

4

4 回答 4

31

这个问题有点误导,因为 . closest() 可能会被误解。实际上,这意味着搜索树,直到找到第一个匹配项。所以相反的是向下搜索树直到找到匹配并且该方法是first().

要查找所有可能使用的后代find()。的反义词find()parents()

最接近()(所有级别) 对于集合中的每个元素,通过测试元素本身并遍历其在 DOM 树中的祖先来获取与选择器匹配的第一个元素。

first()(所有级别) 将匹配元素的集合减少到集合中的第一个

parents()(所有级别) 获取当前匹配元素集中每个元素的祖先,可选地由选择器过滤。

parent()(仅下一级) 获取当前匹配元素集中每个元素的父元素,可选地由选择器过滤。

find()(所有级别)获取当前匹配元素集中每个元素的后代,由选择器、jQuery 对象或元素过滤。

于 2013-06-13T18:44:02.220 回答
29

假设通过“最近的对面”您想要“最远”的父元素,您可以使用parents().last(),如下所示:

$('.elem').click(function() {
    var $topSubMenu = $(this).parents('.sub-menu').last();
});

请注意,当 jQuery 遍历 DOM 时,您希望数组中的最后一个元素,因此顶级项目将是集合中的最后一个。

于 2013-02-09T11:29:10.830 回答
3

这是一个仅限JavaScript的解决方案,基于closest().

function furthest(s) {
    var el = this.parentElement || this.parentNode;
    var anc = null;

    while (el !== null && el.nodeType === 1) {
        if (el.matches(s)) anc = el;
        el = el.parentElement || el.parentNode;
    }
    return anc;
}
于 2019-07-20T10:37:41.897 回答
0

.closest()实际上可以在这里使用,通过传递一个将匹配元素限制为直接后代的选择器.menu

$('.elem').click(function() {
    let $topSubMenu = $(this).closest('.menu > .sub-menu');
});
于 2021-06-11T12:29:43.067 回答