使用jQuery查找所有“X代”后代

时间:2011-09-17 05:59:26

标签: jquery children descendant

解决了(排序

好吧,我认为我使用以下方法解决了它(禁止边缘情况):

function findByDepth(parent, child, depth){
    var children = $();
    $(child, $(parent)).each(function(){
        if($(this).parentsUntil(parent, child).length == (depth - 1)){
            children = $(children).add($(this));
        }
    });
    return children;
}

// this would successfully return the 3.X elements of an HTML snippet structured
// as my XML example, where <parent> = #parent, etc.
var threeDeep = findByDepth('#parent', '.child', 3);

然而有人必须在这里得到接受的答案,我不打算自己回答这个问题并且与你赚得好的代表潜逃。所以,如果有人想要添加任何内容,例如提供对优化此功能的深入了解(我去之前和$.extend() ),我可能会将您的答案标记为正确,否则会回归到在最初的问题上标记谁是第一个。

顺便说一句,请在小提琴中查看:http://jsfiddle.net/5PDaA/

子更新

再看看@ CAFxX的答案,我意识到他的方法可能更快,在浏览器中利用querySelectorAll可以。无论如何,我修改了他对下面的方法,但它仍然给了我guff:

$.fn.extend({
    'findAtDepth': function(selector, depth){
        var depth = parseInt(depth) || 1;
        var query = selector;
        for(var i = 1; i < depth; i++){
            query += (' ' + selector);
        }
        return $(query, $(this)).not(query + ' ' + selector);
    }
});

第一次工作正常,但是当上下文更改为selector中的元素时,它会因某种原因失败。


更新

好吧,我愚蠢地不清楚,并且对我所做的事情的规格一无所知。自从我查看了我的实现后,我将在这里更新;我会标记满足我最初要求的最早答案,因为人们认为我是一个无条件更新的傻瓜(我不会责怪你)但是我的奖金提到下面是基本上是要求。我发布了另一个问题,但它可能会因重复而被关闭。无论如何,为了您的耐心,+ 1都在附近:

给定孩子的深度规范是必要的(给它包裹在一个函数或其他中),从而隔离一个孩子并同样嵌套(不一定是兄弟姐妹< / em>)匹配元素。

例如( XML for brief ):

<!-- depth . sibling-index-with-respect-to-depth -->

<parent>
    <child>                     <!-- 1.1 -->
        <child>                 <!-- 2.1 -->
            <child>             <!-- 3.1 -->
                <child></child> <!-- 4.1 -->
            </child>            
            <child>             <!-- 3.2 -->
                <child></child> <!-- 4.2 -->
            </child>            
        </child>                
        <child>                 <!-- 2.2 -->
            <child></child>     <!-- 3.3 -->
        </child>                
    </child>                    
</parent>

给定2指定的深度,选择所有2.X个元素。给定4全部4.X,依此类推。


原始问题

使用jQuery的本机功能,有没有办法只选择与选择器匹配的“第一代”后代?例如:

注意:以下仅为示例。 .child个元素嵌套在任意级别的父级中。

Bonus :正如我在下面提出的语法所示,一个答案提供了一种方法来指定选择应该遍历的深度令人难以置信。< / em>的

// HTML
<div id="parent">
    <div>
        <div class="child"> <!-- match -->
            <div>
                <div class="child"> <!-- NO match -->
                </div>
            </div>
        </div>
        <div class="child"> <!-- match -->
            <div>
                <div class="child"> <!-- NO match -->
                </div>
            </div>
        </div>
    </div>
</div>

// jQuery
$('#parent').find('.child:generation(1)'); // something in that vein

尝试从#parent的上下文中进行选择,jQuery :first在这里不起作用,因为它只会遇到第一个匹配的.child

3 个答案:

答案 0 :(得分:2)

试试这个(KISS!):

$("#parent .child").not(".child .child");

编辑:获得第二级:

$("#parent .child .child").not(".child .child .child");

第三个:

$("#parent .child .child .child").not(".child .child .child .child");

依此类推......所以你可以(未经测试):

function findChildrenDeepDown(parentSelector, level) {
  level = parseInt(level);
  var firstSelctor = parent, notSelector = ".child", i;
  for (i=0; i<level; i++) {
    firstSelector += " .child";
    notSelector += " .child";
  }
  return $(firstSelector).not(notSelector);
}

findChildrenDeepDown("#parent", 3); // find third-level children of #parent

答案 1 :(得分:1)

你可以这样得到它:

$("#parent").find(">div>.child")

修改

如果第一个孩子可以处于随机深度,您可以使用

$("#parent").find(".child").siblings();

答案 2 :(得分:1)

一般来说,我认为你必须找到所有.child元素,然后扔掉那些拥有.child祖先的元素:

$('#parent .child').filter(function() {
    return $(this).parent().closest('.child').length == 0;
});

虽然这不会处理这样的事情:

<div id="parent">
    <div class="child"> <!-- match -->
        <div>
            <div class="child"> <!-- NO match -->
            </div>
        </div>
    </div>
    <div>
        <div>
            <div class="child"> <!-- NO match wanted but it will match -->
            </div>
        </div>
    </div>
</div>

但也许对于HTML的结构就足够了。