2009-06-29 18 views
60

Estoy en el proceso de implementar jQuery, y de eliminar las bibliotecas Prototype en mi base de código, y me pregunto si podría darme la mejor manera de implementar esta funcionalidad en jQuery. Estoy familiarizado con la sintaxis descendiente jQuery >, pero solo quiero comprobar si un elemento es un descendiente por verdadero o falso, como el siguiente código: ¿alguien me puede dar la solución jQuery más eficiente para esto?La mejor manera de averiguar si el elemento es descendiente de otro

<div id="australopithecus"> 
    <div id="homo-herectus"> 
    <div id="homo-sapiens"></div> 
    </div> 
</div> 

$('homo-sapiens').descendantOf('australopithecus'); 
// -> true 

$('homo-herectus').descendantOf('homo-sapiens'); 
// -> false 
+2

víctima: Use 'http://stackoverflow.com/questions/865486/how-can-i-check-if-an-element-is-within-another-one-in-jquery/865551 –

+4

jQuery.contains() '. Ver mi respuesta a continuación. – TLindig

Respuesta

29

Me gustaría pensar que podría tomar ventaja de la selección de estilos CSS aquí, con longitud devuelta.

$('#australopithecus #homo-sapiens').length // Should be 1 
$('#homo-sapiens #homo-herectus').length // Should be 0 

No exactamente verdadero/falso, pero verificar 0/1 como booleano debería funcionar. :)

Alternativamente, podría hacer algo como $ ('# parent'). Find ('# child') y verificar la longitud allí.

+1

gracias por todas las buenas respuestas !! No me di cuenta que tenía tantas opciones :) – 29er

+1

¡Gracias! Y puedes "convertirlos" en 'true' /' false' anteponiendo '!!', como '!! $ ('# australopithecus # homo-sapiens'). Length', que devuelve' true'. –

+0

No hay necesidad de convertir estos a nada más, ya que en javascript falso, 0, nulo y NaN se cuentan como falsos cuando se usan en sentencias if ... –

3

Se podría tratar de .find() en los Elementos .children()

$("#lucy").find("#homo-erectus").length; 

O la dirección opuesta:

$("#homo-erectus").parents().find("#lucy").length; 
+0

No conozco la sintaxis de jQuery, pero sería más rápido verificar los padres() del elemento descendiente, en lugar de todos los hijos del antepasado, ¿verdad? – harpo

+0

@harpo, Potencialmente. Dependiendo de los usuarios, DOM en particular. Buen consejo, definitivamente, algo que considerar. – Sampson

21

¿Qué tal


$("#homo-herectus").parents().is("#australopithecus"); 
-1
function descendantOf(parentId, childId) { 
    return ($('#'+parentId+' > #'+childId).length === 1); 
} 

Eso debería funcionar.

Como se ha señalado en el comentario anterior, si no se quiere que sea justo descendientes directos:

function descendantOf(parentId, childId) { 
    return ($('#'+childId, $('#'+parentId)).length === 1); 
} 
+3

El uso del carácter> en el selector limitará la verificación solo a los decdendants de primera generación. Si desea verificar si se trata de algún tipo de descendiente (a diferencia del descendiente directo), simplemente elimine el carácter>. –

5

Usted puede utilizar la función de is() así:

alert($('#homo-sapiens').is('#australopithecus *')); 
// -> true 

alert($('#homo-herectus').is('#homo-sapiens *')); 
// -> false 
+4

¿No crees que usar * (asterisco) es demasiado caro ya que controla a todos los niños sin detenerse en la primera coincidencia? –

-1

Suponiendo que volver a escribir su declaración inicial en:

$('#homo-sapiens').descendantOf('#australopithecus'); 

tratar de plugin:

(function($) { 
    $.fn.descendantOf = function(parentId) { 
     return this.closest(parentId).length != 0; 
    } 
})(jQuery) 
4
$.fn.descendantOf = function(element) { 
    element = $(element)[0]; 
    var current = this; 
    var body = document.body; 
    while (current && current != element && current != document.body) { 
     current = $(current).parent()[0]; 
    } 
    if (typeof(current) == "undefined" || typeof(current) == "null") { 
     return false; 
    } else if (current == element) { 
     return true; 
    } else if (current == document.body) { 
     return false; 
    } 
} 

Ejemplo :

<div id="foo"> 
    <div id="bar"> 
     <div id="baz"></div> 
    </div> 
</div> 

Y:

$('#foo').descendantOf('#bar'); // false 
$('#foo').descendantOf('#foo'); // false 
$('#foo').descendantOf(document.body); // true 
$('#bar').descendantOf('#foo'); // true 
$('#baz').descendantOf('#foo'); // true 
+0

'typeof' no es una función, es una palabra clave. No necesita los paréntesis, aunque sigue siendo válido.'typeof current ==" undefined "' – SeinopSys

103

En jQuery 1.6, puede utilizar el siguiente código de forma genérica, por ejemplo, targetElt y parentElt pueden ser ambos elementos DOM u objetos envueltos-jQuery, así como selectores:

$(targetElt).closest(parentElt).length > 0 

Algunas de las otras respuestas requieren que se refieren a los elementos por sus identificadores, que no es útil si todo lo que tiene es un elemento DOM sin una ID.Además, si desea asegurarse de que targetElt es un descendiente estricto de parentElt (en otras palabras, no desea contar parentElt como su propio descendiente), asegúrese de agregar una verificación targetElt != parentElt antes de llamar al .closest(), o use .parents().find() como lo sugiere Jonathan Sampson.

+3

Exactamente lo que quería saber, gracias. –

+1

Esta debería ser la respuesta aceptada. Todas las otras respuestas en esta pregunta y el dup requieren conocer las ID/clases. Este es perfectamente transparente para todo lo que –

+2

0 es falsey por lo que simplemente puede usar $ (targetElt) .closest (parentElt) .length como condición. (es decir, sin verificar la longitud es> 0) – ensignr

2

mejor método que he encontrado es el uso de Dan G. Switzer, el método de la Segunda encontrar aquí: http://blog.pengoworks.com/index.cfm/2008/9/24/Using-jQuery-to-determine-if-an-element-is-a-child-of-another-element

jQuery.fn.isChildOf = function(b){ 
    return (this.parents(b).length > 0); 
}; 

allí tendría que sólo tiene que utilizar el plugin como:

$('homo-sapiens').isChildOf('australopithecus'); 
// -> true 

$('homo-herectus').isChildOf('homo-sapiens'); 
// -> false 
+1

Esto solo determina un único nivel de descendencia –

+0

@MildFuzz Estoy bastante seguro de que estás equivocado al respecto. 'parents()' atraviesa todo el árbol para buscar una coincidencia. https://api.jquery.com/parents/ –

39

con jQuery> = 1.4 (2010) puede usar la función muy rápida jQuery.contains()

Este método estático funciona con elementos DOM, no con elementos jQuery a nd devuelve true o false.

jQuery.contains(container, descendant) 

Ejemplo: Para comprobar si un elemento se encuentra en el documento que puede hacer esto:

jQuery.contains(document.body, myElement) 

Actualización:

También hay un método DOM nativa Node.contains() que todos los navegadores desde ie5 + soportes. Por lo que puede hacerlo sin jQuery:

document.body.contains(myElement) 
+1

Esta es la respuesta correcta. – Andy

+0

Puede usar objetos jQuery tirando del elemento DOM del objeto agregando "[0]" -> https://learn.jquery.com/using-jquery-core/faq/how-do-i-pull-a -native-dom-element-from-a-jquery-object / –

0

Una alternativa a la más cercana() que utiliza (casi) el mismo principio transversal y no incluye el elemento en sí: child.parentsUntil(ancestor).last().parent().is(ancestor).

var child = $('#homo-sapiens'); 
var ancestor = $('#australopithecus'); 

console.log(child.parentsUntil(ancestor).last().parent().is(ancestor)); // true 
Cuestiones relacionadas