In the following example the stored jQuery selector
returns the wrong value. There is a possibility to store the selectors and not the result?
The js code:
// 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<10; ++i ){ $container.append( $(element_html) ); } // try the stored selectors -> returns 0 console.log( "1: " + $element1.length ); console.log( "2: " + $element2.length ); console.log( "3: " + $element3.length );
Why, if I use the container selectors to find the elements, it works? It is beacuse the selector returns the pointer
to the matched elements and not the elements?
// this works console.log( "1: " + $container.find( '.element' ).length ); console.log( "2: " + $( '.element', $container ) .length ); console.log( "3: " + $( '.element' ) .length );
jsFiddle demonstration
element' ), $element2 = $( '. element', $container ), $element3 = $( '. element' ); // append elements to the container for( i=0; i<10; ++i ){ $container. append( $(element_html) ); } // try the stored selectors -> returns 0 console.
JavaScript (jQuery) variable will have only two scopes. Global Variables − A global variable has global scope which means it is defined everywhere in your JavaScript code. Local Variables − A local variable will be visible only within a function where it is defined.
You have a fundamental misunderstanding of what
variableName = $("selector here");
does. It does not "store the selector." It runs the selector you give against the current elements in the DOM, creates a jQuery object, puts the matching elements in the jQuery object, and gives you a reference to that jQuery object. The selector is not stored (modulo jQuery internals).
So given:
<body> <div class="foo">x</div> </body>
Then:
var $divs = $("div.foo"); console.log($divs.length); // 1
Gives us this:
If we then add another matching div
:
$('<div class="foo"></div>').appendTo(document.body);
Our $divs
still only points to the first one; adding another matching element to the DOM had no effect on the jQuery object referenced from $divs
.
If we re-run the query at that point:
$divs = $("div.foo");
...then we have:
If you have a jQuery object containing a DOM element, and you add descendant elements to that DOM element, then using that jQuery object with (say) .find
will see the descendants. That's because the parent DOM element is already there in the jQuery object. E.g., adding a span
to one of the div
s that we already reference from our jQuery object:
If we were to use .find
on $divs
at that point looking for a span
, we'd find it, because it's a descendant of one of the elements we already had a reference to.
If you want to re-run the DOM search again later to look for matching elements, you just use $()
again; this is implicit in the above, but for clarity:
var $divs = $("div.foo"); console.log($divs.length); // 1 $('<div class="foo"></div>').appendTo(document.body); console.log($divs.length); // Still 1 $divs = $("div.foo"); console.log($divs.length); // Now it's 2
So "storing a selector," when needed, is a matter of storing the selector string somewhere, not the jQuery object.
I think the accepted answer is excellent, but it could be interpreted to suggest that assigning JQuery objects to variables is always unsafe. Doing so is fine -- as long as the DOM object the variable references is not altered before you access it in a way that affects later code.
HTML
<div id="banner-message"> <p>Hello World</p> <button>Change view</button> </div>
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With