代码之家  ›  专栏  ›  技术社区  ›  DA.

jQuery筛选选择器删除匹配模式的嵌套元素

  •  6
  • DA.  · 技术社区  · 14 年前

    给定此示例标记(假设 .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时 我只想和b区匹配。换句话说,我想排除嵌套 .外部

    我想有削减的外部和内部(s)包含在他们的嵌套水平。

    我希望如此 .filter() 可以完成它,但是想不出一个选择器可以通用于无限嵌套模式。使用过滤器是否可行?或者直接选择模式?

    更新:

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

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

    更新2:

    我应该直截了当地提到这一点: .内部 但不一定是直系子女。

    更新3:

    下面是一些可以使用的HTML测试示例。在每种情况下,我都希望能够选择.outer并将其包含的.inner与嵌套的outer配对。为了清楚起见,我为每个div添加了名称(outer-x对和inner-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>
    

    我想我最终走上了一条和格纳夫相似的道路。最后我得到了这个:

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

    6 回复  |  直到 14 年前
        1
  •  12
  •   gnarf    14 年前

    这是另一个选择。假设你有 .outer o ,这将选择全部 inner

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

    它的工作原理应该与gnarf的答案相同,但要简单一点。

    首先,它找到了一切 在这下面是什么 outer .
    inners 是其他人的后代 outers

    http://jsfiddle.net/Zb9gF/

    使用此方法比使用 .filter() http://jsperf.com/selector-test-find-not

        2
  •  2
  •   gnarf    14 年前

    如果 .inner .outer 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

        3
  •  1
  •   jasongetsdown    14 年前
    $('.outer').children('.inner');
    

    inner outer . 我不太清楚你要选哪个部门。是a、b、c还是d?把一个叫做“外”的东西嵌套在一个叫做“内”的东西里是没有意义的。也许你能举个更具体的例子?

        4
  •  1
  •   azatoth    14 年前

    .inner .outer ,除非有 在这两者之间,也许以下方法可行(未经测试):

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

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

        5
  •  0
  •   Ionuț Staicu    14 年前

    你可以使用一些css魔法:

    $('.outer>.inner')
    

    应该只给你第一层 .inner 元素。:)

        6
  •  0
  •   vittore    14 年前

    我想知道为什么不选择 .inner closest .outer ?

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

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

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