2011-01-17 49 views
16

Esto parece algo ordenado que podría estar "integrado" en jQuery, pero creo que todavía vale la pena preguntarlo.Iterar a través del nivel N Niños

Tengo un problema donde eso se puede resolver fácilmente iterando a través de todos los elementos secundarios de un elemento. Recientemente descubrí que necesito dar cuenta de los casos en los que necesitaría hacer un nivel o dos más profundo que el "1 nivel" (simplemente llamé .children() una vez) Actualmente estoy haciendo.

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

Esto es lo que estoy haciendo actualmente. Para ir a una segunda capa de profundidad, ejecuto otro ciclo después de hacer código de material para cada elemento.

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

Si quiero ir a un nivel más profundo, tengo que hacer esto una vez más.

Esto claramente no es bueno. Me encantaría declarar una variable de "nivel" y luego tener todo cuidado. ¿Alguien tiene alguna idea para una solución jQueryish limpia y eficiente?

Gracias!

+0

¿Qué es lo que buscas en los elemtns? – amosrivera

+0

+1 porque estoy sorprendido de que jquery no tenga un selector nativo para esto, y porque extraño un poco el cruce manual dom lol. – goat

Respuesta

6

Esta es una pregunta increíble debido a los niveles de captura profunda. Check out the fiddle.

Se ha convertido en un complemento.

Activa

$('#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

Haz que solo filtre cosas en lugar de ser un visitante de capacidad limitada. Más jquery'ish/flexible imo. – goat

+0

@chris - No puedo ver cómo obtener todos los elementos dentro de un contenedor, luego el filtrado basado en un selector dinámico podría ser más flexible/eficiente –

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); 

Asegúrese de que usted pone su código de "hacer cosas" en el lugar correcto si las cosas que ordenan las "cosas" se realiza en.

+1

'--depth' no funcionará fyi –

2

Esta pregunta es impresionante :-)

Si usted sabe que su DOM no es demasiado gigantesca, sólo podría encontrar todos los descendientes y filtrar los que no cumplen los requisitos:

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

Después de eso, la instancia de jQuery "$ childrenWithinRange" sería todos los nodos secundarios de ese padre <div> que están dentro de una profundidad máxima. Si quería exactamente esa profundidad, cambiaría "<" a "===". Puede que me vaya por ahí en alguna parte.

+0

+1 Así es como lo haría, a menos que sintiera que estaría filtrando demasiadas cosas a descendientes muy profundos. – goat

1

Usted debe ser capaz de simplemente lo hacen con el all-selector(docs), la child-selector(docs) y multiple-selector(docs) así:

Ejemplo:http://jsfiddle.net/mDu9q/1/

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

...o si única quería apuntar a los niños de 3 niveles de profundidad, se puede hacer esto:

Ejemplo:http://jsfiddle.net/mDu9q/2/

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

Estos dos selectores son válidos para querySelectorAll, lo que significa aumento considerable de rendimiento en navegadores compatibles.

Cuestiones relacionadas