2013-03-29 81 views
0

假設我有一個像DOM:jQuery的選擇與類頂級後代

<body> 
<div class="a" data="a"><!-- 1 --> 
    <div> 
     <div class="a" data="b"><!-- 2 --> 
     </div> 
    </div> 
    <div class="a" data="c"><!-- 3 --> 
     <div class="a" data="d"><!-- 4 --> 
      <div class="a" data="e"><!-- 5 --> 

      </div> 
     </div> 
     <div class="a" data="f"><!-- 6 --> 
      <div class="a" data="g"><!-- 7 --> 

      </div> 
     </div> 
    </div> 
</div> 
<div> 
    <div class="a" data="h"><!-- 8 --> 

    </div> 
</div> 
</body> 

我怎麼能選擇具有類a匹配元素的頂級元素?

例如$('body').selector...應該選擇1和8 $('[data="a"]').selector...應選擇2和3 $('[data="c"]').selector...應選擇4和6 請注意HTML結構僅僅是一個例子,它可以具有任何其它結構。

+0

這似乎與[這個問題]類似(http://stackoverflow.com/questions/15712377/match-only-the-first-descendent-in-pure-css),問了幾分鐘,除了一個是尋找純粹的CSS。 – Barmar

+0

@Barmar我不認爲這可以用純粹的CSS選擇器來完成,或者至少不是一個非常可怕的CSS選擇器:-)我不知道如何指定排除中間子選擇器的祖先關係。 – Pointy

回答

0

我已經通過添加自己的選擇來解決它:

$.fn.topLevel = function(sel) { 
    var master = $(this); 
    return master.find(sel).filter(function() { 
    return $(this).parentsUntil(master,sel).length == 0; 
    }); 
}; 

,但我仍然認爲,有更多的棘手解決方案。

0

做這樣的事情的一個好方法(雖然稍微有些棘手)是想想它的後退。要找到(在你的例子)1和8,你可以這樣做:

var oneAndEight = $('.a').filter(function() { 
    return $(this).parents('.a').length === 0; 
}); 

這就是所有的名爲「.a」,沒有其他的名爲「.a」元素更接近DOM根元素。要得到2和3,你需要在元素和根之間只有一個「.a」。

一概而論,這裏有一個簡單的插件:

$.atDepth = function(sel, depth) { 
    return $(sel).filter(function() { 
    return $(this).parents(sel).length == depth; 
    }); 
}); 

拿到1和8:

var oneAndEight = $.atDepth(".a", 0); 

對於5和7:

var fiveAndSeven = $.atDepth(".a", 3); 

我不認爲這可以用一個簡單的選擇器完成,因爲CSS選擇器語法沒有「任何不包括x」機制。

編輯here is a jsbin;

+0

$(this).closest('。a')將選擇元素本身,如果它有class a,所以什麼也不會返回 –

+0

@AkramBerkawy對不起,我的意思是「父母()」不是「最接近()」oops ... – Pointy

+0

@AkramBerkawy固定。我一定很困:-) – Pointy

0

這似乎做到這一點:

$(".a:not(.a .a)") 
+0

這將如何從$('[data =「c」]')'開始選擇4和6? –