5

解决了(有点

好吧,我想我使用以下方法解决了它(排除边缘情况):

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()使用之前),我可能会将您的答案标记为正确,否则会退回到标记我最初问题的第一个人。

顺便在fiddle中检查一下:http: //jsfiddle.net/5PDaA/

子更新

再次查看@CAFxX 的答案,我意识到他的方法可能更快,可以利用querySelectorAll浏览器。无论如何,我将他的方法修改为以下内容,但它仍然让我大笑:

$.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 随时为您提供耐心:

给定孩子的深度规范是必要的(假设它被包装在一个函数中或以其他方式),因此隔离了一个孩子和同样嵌套的(不一定是兄弟姐妹)匹配元素。

例如(为简洁起见 XML):

<!-- 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元素嵌套在任意级别的父级中。

奖励:正如我在下面提出的语法所示,提供一种方法来指定选择应该遍历的深度的答案将是令人难以置信的。

// 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.

4

3 回答 3

2

试试这个(亲吻!):

$("#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
于 2011-09-17T06:09:13.387 回答
1

你可以像这样得到它:

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

编辑

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

$("#parent").find(".child").siblings();
于 2011-09-17T06:06:16.477 回答
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 结构。

于 2011-09-17T06:15:13.197 回答