2011-06-28 37 views
2

我們正在使用一個框架來創建由屬性data-type=[some data type]標識的任意嵌套的HTML數據元素。其中每個可以包含直接輸入字段以及其他data-type,可以是單例或數組。嵌套結構唯一的優點是在任何深度都不會包含相同類型的data-types複雜的JQuery選擇器 - 如何選擇一個任意的「代」?

的HTML我必須工作,

<div data-type='project' id='example1'> 
    <input name='start-date'/> 
    <div data-type='project-lead' id='example2'> 
    <input name='department'/> 
    <input name='email'/> 
    <div data-type='analyst'>  
     <input name='department'/> 
     <input name='email'/> 
    </div> 
    <div data-type='analyst'>  
     <input name='department'/> 
     <input name='email'/> 
    </div> 
    <div data-type='analyst'>  
     <input name='department'/> 
     <input name='email'/> 
    </div> 
    </div> 
    <div class="JustToMakeMyLifeMoreDifficult"> 
    <div data-type='sponsor'>  
     <input name='department'/> 
     <input name='email'/> 
    </div> 
    <div data-type='sponsor'>  
     <input name='department'/> 
     <input name='email'/> 
    </div> 
    </div> 
</div> 

選擇問題

我需要一個jQuery找到選擇它得到了我一套data-type要素之一data-type水平下方給定對象:

myData($obj){ 
    return $obj.find('[data-type]').not([data-type elements further down]); 
} 

使得:

myData($('#example1')) 
myData($('#example2')) 

分別得到jQuery的結果:

[project-lead,sponsor,sponsor] 
[analyst, analyst, analyst] 

JQuery的嚮導,請幫助我。你是唯一可以的。

回答

這是不可能的jQuery選擇。我裹着帕特里克下面很優雅的解決方案爲廣義JQuery的功能 -

(function($){ 
    $.fn.dataChildren = function(_selector) { 
     var iter = this; 
     var res = this.children(_selector); 
     while ((iter = iter.children(':not(' + _selector +')')).length) { 
       res = res.add(iter.children(_selector)); 
     } 
     return res; 
    }; 
})(jQuery); 

這樣:

$('#example1').dataChildren('[data-type]') 

作品,如上所述。 I < 3 SO。

+0

在我看來,你想要有一個* data- *屬性的div childNodes,而對於那些沒有它的,獲取div的childNodes。那是對的嗎? – RobG

回答

2

編輯2:?我認爲這是你在找什麼:

var el = $('#example1'); 

var res = el.children('[data-type]'); 

while ((el = el.children(':not([data-type])')).length) { 
    res = res.add(el.children('[data-type]')); 
} 

這一個遞歸深,但任何子分支遞歸停止whe ñ一個元素被發現data-type,所以它只會繼續,只要有一個孩子,不是data-type

這可能是更容易執行,如果我用一個do-while循環,放鬆一些代碼:

var el = $('#example1'); // el is the current level 
var res = $();   // res holds the result 
var data_types;   // holds the children with data-type for the current level 

do { 
     // from current level, get children with data-type 
    data_types = el.children('[data-type]'); 

     // add those to the result set 
    res = res.add(data_types); 

     // make the current level be the children of the current level that 
     //  do NOT have data-type 
    el = el.children().not(data_types); 

} while(el.length); // continue as long as the new current level 
         //  has at least one element 

編輯:我可能誤解了一部分。

它看起來像一個元素與data-type可能有孩子,也有data-type。如果是這樣的情況下,選擇改成這樣:

var ex = $('#example1'); 

var res = ex.find('> [data-type], > * > [data-type]'); 

所以總結這一個,它說讓所有兒童孫子有一個data-type屬性。


原來的答覆:

如果我知道你想孩子data-type,而不是data-type,你也需要添加自己的孩子是data-type的孩子。

var ex = $('#example1'); 

var res = ex.find('> [data-type], > :not([data-type]) > [data-type]'); 

這使用multiple-selector[docs]

中的第一選擇是:

'> [data-type]' 

...這將得到具有data-type屬性子。

中的第二選擇是:

'> :not([data-type]) > [data-type]' 

...這將首先得到的是做data-type孩子,但這些,就會讓自己的孩子是data-type

這看起來像你想要的?

+0

這看起來可能是正確的,但我認爲它現在不處理example2。你能否分解那個選擇器的後半部分發生了什麼? – RSG

+0

@RSG:你在說哪一個。我的「原始答案」或「編輯」。再看一遍,「原始答案」確實符合示例輸出,但我不確定它是否符合您的描述。 – user113716

+0

我剛纔在談論最初的答案,我們的帖子越過了。 :)更新是有幫助的,但如果我正確讀取它,則會在兩個DOM級別找到數據類型的子代。 IRL還有更多JustToMakeMyLifeMoreDifficult divs - 我必須編寫n個版本的> *>選擇器,對吧? – RSG

0

$obj.find('> [data-type]'); 

,如果我得到你的問題所在應該工作。

選擇'> [data-type]'的意思是「給我有‘數據型’的界定,是容器的直接子的所有元素

+0

謝謝,但有任意的標記div(如示例),使這不起作用。 – RSG

0
$obj.children().map(function() {return this.name;}) 

也許

1

一個POJS函數,你想要做什麼,並返回匹配元素的數組是:

function getNodes(id) { 
    var el = (typeof id == 'string')? document.getElementById(id) : id; 
    var result = []; 
    var node, nodes = el.childNodes; 
    var prop = 'data-type'; 
    var tag = 'div'; 

    for (var i=0, iLen=nodes.length; i<iLen; i++) { 
    node = nodes[i]; 

    if (node.tagName && node.tagName.toLowerCase() == tag) { 

     if (node.getAttribute(prop)) { 
     result.push(node); 

     } else { 
     result = result.concat(getNodes(node)); 
     } 
    } 
    } 
    return result; 
} 

但是,我不知道你希望它去的這樣深一個可能。它可以修改爲只能達到一定的深度(比如一個或兩個級別)。

+0

任意深度是一個需求,如果jquery沒有合適的話,我可能不得不使用類似的東西。 – RSG