2011-03-25 10 views
22

Dado un objeto jQuery, $j, necesito saber si representa algo que ya está en la página o si es algo que aún no se ha puesto en la página. Por ejemplo, si tengo esto:Detecta si un objeto jQuery está en la página o no

$j = $('#id-of-something-already-on-the-page'); 

o

$j = $('<p>Where is pancake house?</p>').appendTo($('#this-is-already-there')); 

Entonces tengo algo en la página y que no es necesario ponerlo en la página. Pero, si acabo de tener esto:

$j = $("<p>I'll cook you some eggs, Margie.</p>"); 

Entonces tendría que anexarlo antes de que esté en la página.

La pregunta es ¿cómo se pregunta $j si está en la página o no? Sé de dos maneras que el trabajo es lo suficientemente bueno:

  1. Ver si tiene un padre: $j.parent().length > 0 implica que está en la página.
  2. Vea si tiene un índice válido: $j.index() > -1 implica que está en la página.

puedo ver la primera fallando si $j es el html o posiblemente body; Estoy feliz de ignorar esos dos casos patológicos. No se me ocurre ninguna forma de que el segundo enfoque fracase.

¿Existe una técnica estándar para preguntar si un objeto jQuery está en la página o no? No me importa si $j es visible.

+5

$ j podría tener un padre y no estar en el documento que se sabe ... – jcolebrand

+3

otra posible prueba:. '$ J.closest ('cuerpo') size()> 0' –

+0

@drachenstern: Buen punto . La mejor parte de hacer una pregunta es hacer que alguien señale los problemas obvios. El mismo problema, presumiblemente, también se aplicaría al enfoque de índice ya que están verificando cosas similares. –

Respuesta

31

En lo personal, me gustaría empezar por descender de un elemento que sabes es en la página, al igual que <html> o <body>, y utilizar .has():

if ($('html').has($j).length) 
{ 
    // $j is in the page 
} 

Esto funciona incluso para los dos casos patológicos que usted ha mencionado. Es more idiomatic para verificar .length en lugar de .size(). Tampoco hay motivo para verificar que el valor devuelto sea > 0.La propiedad length será siempre ser un entero no negativo, por lo que es suficiente para verificar la veracidad del valor.

+3

Hay una buena razón para '> 0' y eso es legibilidad. Sin embargo, puede no valer la pena las pulsaciones de teclas adicionales, especialmente cuando la mayoría de los codificadores de JavaScript entenderán el significado sin él. – Muhd

+0

Tengo una preocupación leve sobre el peso de esto en páginas grandes. Pero +1, es seguro. – ANeves

-1

El objeto jQuery representa una colección de elementos html.

Después de su selección: $ j = $ ('# id-of-something-already-on-the-page');

Todo lo que tienes que hacer es marcar $ j.length. Si es uno, hay un elemento en la página.

+0

No es cierto. Si desconecto el nodo y lo almacena en una variable, todavía existe como una variable. Si más tarde pruebo esa variable para ver si algún código lo reinsertó en el DOM (piense: pasar una referencia en lugar de volver a filtrar para ello cada vez, y declaraciones de bifurcación para hacer varias acciones como separar o ajustar) entonces puede o no ser en el DOM. No siempre se puede saber cuál será el ID, si está escribiendo una función donde pasa una referencia a un nodo. También: consulta de contexto. – jcolebrand

+0

O si tengo '$ j = $ ("

te cocinaré unos huevos, Margie.

")' luego '$ j.length == 1' pero el párrafo no aparece en la página hasta que' '$ ('body'). append ($ j) '(o algo similar) para insertarlo en el DOM. –

6

probablemente me acaba de comprobar para ver si el elemento puede alcanzar el elemento del cuerpo:

$j.closest('body').size()>0 

Como se anotó en otros comentarios, esto sería fallar en algunos casos excepcionales en los que están manejando los elementos del cuerpo adicionales. Si realmente desea detectar esas situaciones, supongo que podría verificar si tiene varios elementos $ (body), pero sospecho que casos tan extremos se saldrán de control muy rápidamente.

Este "es, probablemente adjunta-a página" cheque se podría convertir en un bona-fide jQuery selector, también:

$.expr[':'].isProbablyAttached = function(obj){ 

    return $(obj).closest('body').size()>0; 
}; 

// Usage: 
$('.someClasses:isProbablyAttached').doSomething(); 
+0

He usado '$ .expr' antes, pero solo necesito esto en un lugar por ahora, así que no creo que deba ser tan elegante. Todavía. –

+1

@Michael @mu ¿Por qué no 'closer ('html')'? –

+0

¿Por qué usar '.size()> 0' cuando puedes simplemente usar' .length'? http://docs.jquery.com/Frequently_Asked_Questions#How_do_I_test_whether_an_element_exists.3F –

3

con jQuery (al menos con la versión 1.7.1) $('html').parent() devuelve una matriz que no esté vacía ([#document]):

$j = $("<p>I'll cook you some eggs, Margie.</p>"); 
$j.parent().length === 0 
$('html').parent().length === 1 
$('body').parent().length === 1 

Así 'mu es demasiado corto' de la nota no es un problema:

Puedo ver la primera falla si $ j es el html o posiblemente el cuerpo; Estoy feliz de ignorar esos dos casos patológicos. No se me ocurre ninguna forma de que el segundo enfoque fracase.

Cuestiones relacionadas