2012-11-09 34 views
10

我有一個像jQuery的:找到()的孩子,直到某一閾值元素時遇到

<table> 

     <td id="first"> 

      <div class="wrapper"> 
       <input name=1> 
      </div> 

      <input name=2> 

      <table> 

       <td id="second"> 

        <input name=3> 

嵌套表結構有我的jQuery選擇$("#first")。我想在<td>的上下文中遍歷並find()所有子項<input>s,但不能下降到嵌套的<table> s。

所以我需要一個jQuery的伎倆,其

  • find()某個元素

  • 的所有子元素將血統n級倒在DOM樹

  • 但將停止下降,如果遇到某個元素(<table>),以便選擇器不選擇嵌套表的輸入(將分開處理)

  • 有可能是任何數量的嵌套<table>水平,因此該解決方案應該工作,無論有多少父母<table>或子女<table>是$範圍(「#第一」)中遇到<td>或任何其他<td>

我查了其他jQuery查找,直到問題。他們有答案,但好像他們不填補最後的標準

+0

您認爲您的表格結構在這裏嗎? – freebird

+1

結構是否使用'

'或某個其他元素完成是自然無關的問題 –

+0

我問,因爲你的輸入標籤不好形成也'tr'失蹤。 – freebird

回答

5

this other question也有類似的問題。最終,我終於找到了一個插件,在與一些想要找到一個選擇器的人交流之後。

用法: ExclusiveInputs = $('#first').findExclude('input','table');

// Find-like method which masks any descendant 
// branches matching the Mask argument. 
$.fn.findExclude = function(Selector, Mask, result){ 

    // Default result to an empty jQuery object if not provided 
    var result = typeof result !== 'undefined' ? 
       result : 
       new jQuery(); 

    // Iterate through all children, except those match Mask 
    this.children().each(function(){ 

     var thisObject = jQuery(this); 
     if(thisObject.is(Selector)) 
      result.push(this); 

     // Recursively seek children without Mask 
     if(!thisObject.is(Mask)) 
      thisObject.findExclude(Selector, Mask, result); 
    }); 

    return result; 
} 

(精簡版)

$.fn.findExclude = function(selector, mask, result) 
{ 
    var result = typeof result !== 'undefined' ? result : new jQuery(); 
    this.children().each(function(){ 
     var thisObject = jQuery(this); 
     if(thisObject.is(selector)) 
      result.push(this); 
     if(!thisObject.is(mask)) 
      thisObject.findExclude(selector, mask, result); 
    }); 
    return result; 
} 
2

嗯,我有更好的想法..

var badTable = "table.bad"; //the one you want to avoid 
var $goodInputs = $("#first").find('input').filter(function() { 
    return $(this).closest(badTable).length == 0; 
}); 

這可能會或可能不會對你不夠快。這取決於你不想談論的DOM;)

如果它很慢,只需手工編寫你的算法的代碼。沒有選擇器快捷鍵。

+0

正如問題所述,您不能從上下文中識別哪個表是「壞」的,但它必須適用於沒有特殊類標記的任何嵌套級別 –

3

更新:讓我們再來看看這個。

基本上,你想要的所有<input>元素是#first後裔和不是#first下嵌套多個層次深<td>元素的孩子相匹配。我不確定最後的under #first部分,但實現它允許我們在祖先鏈中支持高於#first<td>元素。)

從技術上講,僅在下面選擇可以滿足您的需要:

var inputs = $("#first td:not(#first td td) > input"); 

如果這不能在瀏覽器中運行(灒應達到我認爲的任務,但像:not()複雜的選擇始終是棘手),您可以委派處理jQuery方法:

var inputs = $("#first td").not("#first td td").children("input"); 

的原件swer如下:

您可以使用not()排除有一個以上的<td>祖先<input>元素:

var firstLevelCells = $("#first").find("input").not("td td input"); 
+1

我不明白;這不需要是$(「#first」)。find(「input」)。not(「td td input」)'? – lnrbob

+0

你說的沒錯,我錯過了跟上比賽的實際元素。回答相應更新,感謝您的領導:) –

1

我也有類似的問題,仍然面臨的挑戰是做一些不帶擴展循環或具有DOM的精確結構。在我的情況下,我已經引用了元素'#first',如果你不這樣做,我們可以使用每個元素(即使它只有一個對象)。訣竅是與父母一起回到樹上,停在你的頂層元素,看看是否有任何中間元素滿足條件。

使用的函數的簡寫拉姆達符號(你可以在打字稿寫),這將導致此:

$('#first').each((idx, f) => $(f).find('input').filter((idx2, inp) => $(inp).parentsUntil(f, 'table').length == 0) 

它可能不是最有效的方法(如您先選擇一切再扔通過再次安裝DOM樹,但它是緊湊的,相當通用的。