2011-01-17 25 views
16

To wydaje się być czymś ładnym, które może być "wbudowane" w jQuery, ale myślę, że nadal warto o to zapytać.Iterowanie przez N Poziom dzieci

Mam problem, który można łatwo rozwiązać przez powtarzanie przez wszystkie elementy elementu. Niedawno odkryłem, że muszę uwzględnić przypadki, w których potrzebowałbym zrobić poziom lub dwa głębsze niż "1 poziom" (tylko raz wywołuję .children()), co obecnie robię.

jQuery.each(divToLookAt.children(), function(index, element) 
    { 
     //do stuff 
    } 
    ); 

Właśnie to robię. Aby przejść na drugą warstwę, uruchamiam kolejną pętlę po wykonaniu kodu materiałowego dla każdego elementu.

jQuery.each(divToLookAt.children(), function(index, element) 
{ 
    //do stuff 
    jQuery.each(jQuery(element).children(), function(indexLevelTwo, elementLevelTwo) 
    { 
     //do stuff 
    } 
    ); 
} 
); 

Jeśli chcę przejść jeszcze głębszy poziom, muszę to zrobić od nowa.

To zdecydowanie nie jest dobre. Chciałbym zadeklarować zmienną "level", a następnie wszystko to załatwić. Ktoś ma jakieś pomysły na czyste, wydajne rozwiązanie jQueryish?

Dzięki!

+0

Czego szukasz w elemtns? – amosrivera

+0

+1, ponieważ jestem zaskoczony jquery nie ma natywnego selektora dla tego, a ponieważ brakuje mi manuala dom traversal lol. – goat

Odpowiedz

6

To jest niesamowite pytanie ze względu na poziom głębokiego połowu. Check out the fiddle.

Przekonwertowano to na wtyczkę.

Aktywuj

$('#div').goDeep(3, function(deep){ // $.fn.goDeep(levels, callback) 
    // do stuff on `this` 
}); 

Plugin

$.fn.goDeep = function(levels, func){ 
    var iterateChildren = function(current, levelsDeep){ 
     func.call(current, levelsDeep); 

     if(levelsDeep > 0) 
      $.each(current.children(), function(index, element){ 
       iterateChildren($(element), levelsDeep-1); 
      }); 
    }; 

    return this.each(function(){ 
     iterateChildren($(this), levels); 
    }); 
}; 
+0

Zrobić to po prostu filtrowanie rzeczy zamiast być ograniczonym gościem możliwości. Więcej jquery'ish/flexible imo. – goat

+0

@chris - Nie widzę sposobu pobierania wszystkich elementów za pomocą kontenera, a następnie filtrowanie w oparciu o dynamiczny selektor może być bardziej elastyczne/wydajne –

0
var lvlFunc = function(elmt, depth) { 
    if(depth > 0) { 
     elmt.children().each(function(i, e){ 
      // do stuff on the way down 
      lvlFunc($(this), --depth); 
      // do stuff on the way out 
     }); 
     // do stuff 
    } 
}; 

lvlFunc(divToLookAt, 3); 

Upewnij się, że można umieścić swój kod „do rzeczy” w odpowiednim miejscu, jeśli sprawy, które Zamów „rzeczy” jest wykonywana w.

+1

'--depth' nie będzie działał fyi –

2

to pytanie jest niesamowite :-)

Jeśli wiesz Twój DOM nie jest zbyt gigantyczny, można po prostu znaleźć wszystkie potomków i odfiltrować te, które nie kwalifikują się:

var $parent = $('#parent'); 
var $childrenWithinRange = $parent.find('*').filter(function() { 
    return $(this).parents('#parent').length < yourMaxDepth; 
}); 

potem wystąpienie jQuery „$ childrenWithinRange” byłoby wszystkie węzły potomne tego rodzica <div>, które znajdują się na maksymalnej głębokości. Jeśli chcesz dokładnie taką głębię, przełączysz "<" na "===". Może gdzieś odejdę.

+0

+1 Tak właśnie bym to zrobił, chyba że czułbym, że odfiltrowuję zbyt dużo rzeczy dla bardzo głębokich potomków. – goat

1

powinien być w stanie po prostu zrób to z all-selector(docs), z child-selector(docs) i multiple-selector(docs) tak:

przykładu:http://jsfiddle.net/mDu9q/1/

$('#start > *,#start > * > *,#start > * > * > *').doSomething(); 

...lub jeśli tylko chciał kierować dzieci głębokich 3 poziomy, można to zrobić:

Przykład:http://jsfiddle.net/mDu9q/2/

$('#start > * > * > *').doSomething(); 

Oba te selektory są ważne dla querySelectorAll, co oznacza duży wzrost wydajności w obsługiwanych przeglądarkach.

Powiązane problemy