Tienda jquery selector en variable

En el siguiente ejemplo, el stored jQuery selector devuelve el valor incorrecto. Existe la posibilidad de almacenar los selectores y no el resultado?

El código js:

 // storing the jQuery selectors var $container = $( '.container' ), $element1 = $container.find( '.element' ), $element2 = $( '.element', $container ), $element3 = $( '.element' ); // append elements to the container for( i=0; i returns 0 console.log( "1: " + $element1.length ); console.log( "2: " + $element2.length ); console.log( "3: " + $element3.length ); 

¿Por qué, si uso los selectores de contenedor para encontrar los elementos, funciona? ¿Se debe a que el selector devuelve el pointer a los elementos coincidentes y no a los elementos?

 // this works console.log( "1: " + $container.find( '.element' ).length ); console.log( "2: " + $( '.element', $container ) .length ); console.log( "3: " + $( '.element' ) .length ); 

demostración jsFiddle

Usted tiene un malentendido fundamental de lo que

 variableName = $("selector here"); 

hace. No “almacena el selector”. Ejecuta el selector que da contra los elementos actuales en el DOM, crea un objeto jQuery, coloca los elementos coincidentes en el objeto jQuery y le da una referencia a ese objeto jQuery. El selector no está almacenado (módulo jQuery internals).

Entonces dado:

  
x

Entonces:

 var $divs = $("div.foo"); console.log($divs.length); // 1 

Nos da esto:

$ divs jQuery objeto apuntando a un div en el DOM

Si luego agregamos otro div correspondiente:

 $('
').appendTo(document.body);

Nuestros $divs solo apuntan al primero; agregar otro elemento coincidente al DOM no tuvo efecto en el objeto jQuery al que se hace referencia desde $divs .

$ divs jQuery objeto que apunta a un div, pero hay dos en el DOM

Si volvemos a ejecutar la consulta en ese punto:

 $divs = $("div.foo"); 

…entonces nosotros tenemos:

$ divs jQuery objeto que apunta a ambos divs en el DOM

Si tiene un objeto jQuery que contiene un elemento DOM y agrega elementos descendientes a ese elemento DOM, entonces usar ese objeto jQuery con (say) .find verá los descendientes. Eso es porque el elemento DOM principal ya está allí en el objeto jQuery. Por ejemplo, agregando un span a uno de los div s que ya hacemos referencia de nuestro objeto jQuery:

$ divs jQuery objeto que apunta a ambos divs en el DOM, uno tiene un lapso ahora

Si .find en $divs en ese punto buscando un span , lo encontraríamos, porque es un descendiente de uno de los elementos a los que ya teníamos referencia.

Si desea volver a ejecutar la búsqueda DOM más tarde para buscar elementos coincidentes, solo usa $() otra vez; esto está implícito en lo anterior, pero para mayor claridad:

 var $divs = $("div.foo"); console.log($divs.length); // 1 $('
').appendTo(document.body); console.log($divs.length); // Still 1 $divs = $("div.foo"); console.log($divs.length); // Now it's 2

Por lo tanto, “almacenar un selector”, cuando sea necesario, es una cuestión de almacenar la cadena del selector en algún lugar, no el objeto jQuery.

Creo que la respuesta aceptada es excelente, pero podría interpretarse como una sugerencia de que la asignación de objetos JQuery a las variables siempre es insegura. Hacerlo está bien, siempre y cuando el objeto DOM las referencias de variables no se modifiquen antes de acceder a él de una manera que afecte al código posterior .

HTML

  

JavaScript

 // find elements var banner = $("#banner-message") var button = $("button") // handle click and add class button.on("click", function(){ banner.addClass("alt"); banner.hide().html("New HTML").fadeIn(2000); }) 

JsFiddle