jQuery过滤选择器,用于删除与模式匹配的嵌套元素

时间:2010-06-22 18:39:27

标签: jquery jquery-selectors

给出此样本标记(假设.outer.inner之间的元素随机数:

<div class="outer">
    <div>
        <div>
            <div class="inner"></div>
        </div>
    </div>
</div>

我可以设置jQuery来选择外部和内部div:

$outer = $('.outer');
$inner = $outer.find('.inner')

工作正常。

但是,假设我想允许无限制地嵌套这个逻辑,所以我可能会这样:

<div class="outer"> div a
    <div class="inner"> div b
        <div class="outer"> div c
            <div class="inner"> div d </div>
        </div>
    </div>
</div>

在这种情况下,当选择div a via .outer时我想将它与div b匹配。换句话说,我想排除嵌套.outer祖先的祖先。

我希望在其嵌套级别中包含外部和内部的parings。

我希望.filter()可以将它拉下来,但是不能想到一个可以无限制嵌套模式普遍使用的选择器。是否可以使用过滤器?或者甚至可能是直接选择器模式?

更新:

我认为这样的事情可行,但不确定如何(或者如果允许的话)在选择器中引用'this':

$outer = $('.outer');
$inner = $outer.not('this .outer').find('.inner')

更新2:

我本应该提到这一点:.inner永远是.outer的后代,但不一定是直接的孩子。

更新3:

以下是一些可以使用的HTML测试样本。在每种情况下,我都希望能够选择.outer并将它本身和嵌套外部之间包含的.inner配对。为清楚起见,我为每个div添加了名称(带有inner-x的外部x对)

//sample 1
<div class="outer"> outer-a
    <div>
        <div class="inner"> inner-a
            <div class="outer"> inner-b
                <div class="inner"> inner-b </div>
            </div>
        </div>
    </div>
    <div>
        <div class="inner"> inner-a </div>
    </div>
</div>

//sample 2
<div class="outer"> outer-a
        <div class="inner"> inner-a
            <div class="outer"> inner-b
                <div>
                    <div class="inner"> inner-b </div>
                </div>
            </div>
        </div>
</div>

//sample 3
<div class="outer"> outer-a
        <div class="inner"> inner-a
            <div class="outer"> inner-b
                <div class="inner"> inner-b
                    <div class="outer"> outer-c 
                        <div class="inner"> inner-c</div>
                    </div>
                </div>
            </div>
        </div>
</div>

//bonus sample (we're trying to avoid this)
<div class="outer"> outer-a
        <div class="inner outer"> inner-a outer-b
            <div class="inner"> inner-b </div>
        </div>
</div>

更新4

我想我最终走上了与gnarf类似的道路。我最终得到了这个:

var $outer = $('.outer');
var $inner = $outer.find('.inner').filter(function(){
    $(this).each(function(){
        return $(this).closest('.outer') == $outer; 
  });                                                                  
});

我是否在正确的轨道上?它没有用,所以我假设我还有一点逻辑错误。

6 个答案:

答案 0 :(得分:12)

这是另一种选择。假设您拥有.outer o,这将选择其下的所有inner

o.find('.inner').not(o.find('.outer .inner'))

它应该与gnarf的答案完全相同,但有点简单。

首先,它会在inner下找到所有outer 接下来,删除作为其他inners

后代的所有outers

互动工作示例:http://jsfiddle.net/Zb9gF/

选择器性能使用此方法似乎要好得多,而.filter()也是如此:http://jsperf.com/selector-test-find-not

答案 1 :(得分:2)

如果.inner始终是.outer s的直接孩子 - children()可能是您最好的选择(jasongetsdown的回答)

如果你需要看起来更深的东西,你可以这样做:

var $outer = $('.outer').first(); // grab the first .outer
$outer.find('.inner').filter(function() {
    // only if the closest parent .outer is the same as the .outer we are looking in
    return $(this).closest('.outer').get(0) == $outer.get(0);
}).css('border','1px solid #000');

jsfiddle demo

答案 2 :(得分:1)

$('.outer').children('.inner');

这将选择位于inner正下方的任何outer。我不太清楚你要选择哪个div。是a,b,c还是d?在内部称为内部的东西中嵌入一些东西并不是很有意义。也许你能提供一个更具体的例子吗?

答案 3 :(得分:1)

如果假设正确,您想要选择.inner下方的所有.outer,除非中间有.outer,否则可能会有以下情况(未经测试):

$('.outer:not(.inner):has(:not(.outer) .inner:not(.outer), > .inner:not(.outer))');

http://jsfiddle.net/cEwBT/1/

上的OP示例HTML测试后更新

答案 4 :(得分:0)

你可以使用一些css魔法:

$('.outer>.inner')

Shold只提供第一级.inner元素。 :)

答案 5 :(得分:0)

我想知道为什么不首先选择.inner,然后获取closest .outer

$inner = $('.inner');
$outer = $inner.closest('.outer');

如果某些内部块可能根本不在外部块中,请使用第一行

$inner = $('.outer .inner');