2011-08-13 6 views
7

¿Cómo puedo seleccionar la primera entrada "más superficial"?¿Cómo puedo seleccionar el descendiente coincidente "más superficial"?

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

<div class="selected"> <!-- already have this --> 
    <div class="unknown-number-of-wrapper-panels"> 
    ... 
    <div class="collection">  
     <div class="child"> 
     <input type="text" value="2" /> <!-- don't want this --> 
     </div> 
    </div> 
    <input type="text" value="2" /> <!-- need this --> 
    <input type="text" value="2" /> 
    ... 
    </div> 
</div> 

Parece que find().first() me da la más profunda.

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 de closest()?

+0

'$ ('más superficial:. First')'? – knittl

+0

@knittl Lo siento ... Acabo de poner esas clases allí para una explicación, tal vez lo voy a editar – Benjamin

+2

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

Respuesta

7

Si entiendo su problema, es necesario comprobar de forma recursiva los nodos secundarios para los 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/


EDIT: había olvidado una instrucción de retorno, y tenía un selector de ID en lugar de un selector de clase de la inicial .selected.


O hacerlo en su propia aduana plugin:

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()); 
+0

+1 - Siéntase libre de robar el código de mi respuesta - Lo eliminaré después. Buen enfoque – gnarf

+0

Un problema que tuve con eso fue que no permitía selectores de atributos de datos ... Para arreglar esto edité la llamada de filtro para usar la función .is jquery para que sea: 'children.filter (function() { \t return $ (this) .is (sel); }); ' – MikingTheViking

3

Busca una búsqueda más amplia en lugar de la búsqueda en profundidad (que usa jQuery's find()). Una rápida de Google ha encontrado: http://plugins.jquery.com/project/closestChild

Esto podría ser utilizado como esto:

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

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

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

Bien dado su marcado, ¿funcionaría lo siguiente?

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

No lo sé. ¿Funcionaría eso teniendo en cuenta que no sabré qué tan baja será la entrada en el árbol? Lo investigaré. – Benjamin

+0

Está buscando obtener una entrada que sea hija directa del padre, en lugar de anidar más adentro. Eso es lo que haría la entrada div> o $ ('div'). Children ('input') en lugar de $ (' div '). find (' input ') que devolverá todas las entradas, independientemente de si es un hijo directo de div o no –

1

Este es otro enfoque.La idea es que se obtiene el elemento coincidente 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'); 

DEMO

findShallowest, as @patrick has it, podría ser un mejor nombre del método;)

3

Solo para jugar al golf este "complemento" un poco - Usa @user113716's technique, solo código reducido.

$.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 la jsFiddle

Cuestiones relacionadas