¿Cómo puedo seleccionar el descendiente que empareja “más superficial”?

¿Cómo puedo seleccionar la primera entrada “más superficial”?

Mi selección actual será la div marcada como “seleccionada”.
No sabré cuántos niveles habrá abajo.

...
...

Parece que find().first() me da el más profundo.

Editado para mayor claridad. Necesito encontrarlo basado en el hecho de que es menos profundo, no en base a otros atributos únicos.

Esto podría ser como un reverso del closest() ?

Si entiendo su problema, necesita verificar recursivamente los nodos secundarios para elementos con esa clase.

 function findShallowest( root, sel ) { var children = root.children(); if( children.length ) { var matching = children.filter( sel ); if( matching.length ) { return matching.first(); } else { return findShallowest( children, sel ); } } else { return null; } } var selected = $('.selected'); findShallowest( selected, ':text' ); 

Ejemplo: http://jsfiddle.net/Qf2GM/


EDITAR: Había olvidado una statement de devolución, y tenía un selector de ID en lugar de un selector de clase para el .selected inicial.


O hágalo en su propio plugin personalizado:

Ejemplo: http://jsfiddle.net/qX94u/

 (function($) { $.fn.findShallowest = function( sel) { return findShallowest( this, sel ); }; function findShallowest(root, sel) { var children = root.children(); if (children.length) { var matching = children.filter(sel); if (matching.length) { return matching.first(); } else { return findShallowest(children, sel); } } else { return $(); } } })(jQuery); var result = $('.selected').findShallowest( ':text' ); alert( result.val() ); 

Está buscando una búsqueda más amplia que la búsqueda en profundidad (que usa jQuery’s find ()). Un rápido google ha encontrado: http://plugins.jquery.com/project/closestChild

Esto podría usarse así:

 $(...).closestChild('input') 

Solo para jugar al golf este “complemento” un poco: usa la técnica de @ user113716 , solo reduce el tamaño del código.

 $.fn.findShallowest = function( selector ) { var children = this.children(), matching = children.filter( selector ); // return an empty set if there are no more children if ( !children.length ) { return children; } // if anything matches, return the first. if ( matching.length ) { return matching.first(); } // check grand-children return children.findShallowest( selector ); }; 

Prueba jsFiddle

Este es otro enfoque. La idea es que obtienes el elemento correspondiente con el menor número de antepasados:

 (function($) { $.fn.nearest = function(selector) { var $result = $(); this.each(function() { var min = null, mins = {}; $(this).find(selector).each(function() { var n_parents = $(this).parents().length, if(!mins[n_parents]) { mins[n_parents] = this; min = (min === null || n_parents < min) ? n_parents : min; } }); $result = $result.add(mins[min]); }); return $result; }; }(jQuery)); 

Uso:

 $('selected').nearest('input'); 

MANIFESTACIÓN

findShallowest , como @patrick lo tiene , podría ser un mejor nombre de método;)

Si no conoce el nombre de clase del elemento de nivel inferior, siempre puede usar algo como

 $('.unknown-number-of-wrapper-panels').children().last(); 

Bien dado su margen de beneficio, ¿funcionaría lo siguiente?

 $('.selected div > input:first')