2011-11-10 14 views
7

Estoy buscando una manera de seleccionar elementos que contienen un elemento determinado y luego filtrar los resultados para obtener solo el nivel más alto. Es difícil de explicar, pero hace más fácil con un ejemplo:jQuery: elementos de nivel más alto que contienen x

<div id="one"> 
    <div id="two"> 
     <div id="three" class="find-me"></div> 
    </div> 
</div> 
<div id="four"> 
    <div id="five" class="find-me"></div> 
</div> 

En este caso, me gustaría que mi conjunto de contener #one y #four. Si trato de hacer algo como esto:

var elements = $('div').has('.find-me'); 

Obtengo los elementos #one, #two y #four.

Nota: Por 'nivel más alto' se relaciona con el elemento superior en el primer selector, $('div') en este caso.

Respuesta

6

Bueno, la definición de lo que es la highest level, es un poco ambigua porque en la práctica si hay alguna .find-me en su página de la más alta de los padres nivel sería html etiqueta! que es inútil.

Al definir su problema más específicamente, puede obtener una definición más clara para este highest-definition y, por ejemplo, decir the farthest div parent et. y para atravesar padres de un elemento, puede usar los métodos .parents() y .closest().

var farthestDiv = $(".find-me").parents("div").last(); 

obviamente, si usted tiene más de un ocurrencias de find-me Tiene que ejecutar esto en un bucle .each().

ver un ejemplo aquí: http://jsfiddle.net/GsQDb/3/

+0

Buen punto - Supongo que es el nivel más alto del primer conjunto; '$ ('div')' en este caso. Me gusta la idea de hacerlo 'al revés' de esta manera. La velocidad es un gran problema en esta página (2 MB de html para recorrer) por lo que estaría interesado en la diferencia de velocidad entre esta respuesta y la respuesta por @karnyj – ajbeaven

0

Si se ponen todos en un gran contenedor div, puede utilizar:

$('.container div.find-me').parents($('.container').children()); 

que debería funcionar, aunque no tengo la oportunidad de probarlo en este momento.

Avíseme si no, ya que también hay soluciones más complejas.

1

utilice un filtro para filtrar los elementos que no coinciden con lo que desea después de su primer selector. ejemplo:

var elements = $('div.find-me').filter(function(idx){ 
    return !$(this).parents('div.find-me').length; 
}); 
0

¿Se puede asignar una clase a la mayor parte de los divs? Si es así usted puede hacer algo como esto:

var elements = $("div.topMost").has(".find-me"); 
+0

No, no en este caso lo siento. – ajbeaven

1

Esto va a hacer lo que quiere, encontrará los elementos primero y luego encontrar los elementos más altos de los y crear un objeto jQuery de los elementos que se encuentran más altos.

var elements = $('div.find-me'), highest = []; 

elements.each(function(){ 
var parent = this, body = document.body; 

    while(parent && parent.parentNode !== body) { 
    parent = parent.parentNode; 
    } 

    if($.inArray(parent, highest) < 0) { 
    highest.push(parent); 
    } 
}); 

highest = jQuery(highest); 

jsFiddle:

http://jsfiddle.net/D3jC8/2/

2

Suponiendo por el "nivel superior", que quiere decir un descendiente directo del cuerpo de la etiqueta, puede utilizar éste revestimiento. Encuentra todos los objetos con una clase .find-me, luego busca en los padres una etiqueta que sea un descendiente de la etiqueta corporal (que será el nivel superior).

$(".find-me").parents("body > *") 

Se puede ver trabajar aquí: http://jsfiddle.net/jfriend00/9LF6u/

Esto tiene las siguientes ventajas:

  1. Cualquier tipo de etiqueta puede ser la etiqueta de nivel superior (no sólo un div)
  2. Se debería ser una de las formas más rápidas de hacerlo, ya que encuentra los objetos .find-me (que serán una operación rápida internamente en la mayoría de los navegadores a través del getElementsByClassName) y simplemente sube su jerarquía principal.
  3. Maneja automáticamente los duplicados para que un elemento de nivel superior determinado nunca se enumere más de una vez.
  4. Si alguna vez quiere cambiar la definición de nivel superior (a un objeto contenedor, por ejemplo), puede simplemente cambiar el selector pasado al método .parents(selector) para reflejar ese cambio.
+0

Mi desconocimiento del manejo duplicado automático de jQuery es la razón por la que fui con la ruta regular js en mi respuesta: PI proa al maestro – Esailija

+0

jQuery objetos creados a través de selectores de filtros nunca tienen duplicados ya que la mayoría de los métodos jQuery terminan con una llamada interna a '.unique()' que filtra dups y pone los selectores en orden de documento. – jfriend00

0
$(".find-me").map(function() { 
    return $(this).parents("div").last().get(); 
}); 
Cuestiones relacionadas