I'm looking for a way to combine jquery variables. Looking through related questions, nobody seems to be trying what I want to do.
$("body, div, p") is one method of combining by selectors, but after you assign a selector to a variable, how do you combine them in a similar fashion?
Here is one method I tried, but did not get it to work. I also tried putting them into an array (by simply adding brackets before $body and after $p).
$body = $("body");
$div = $("div");
$p = $("p");
$mixed = $($body, $div, $p);
// $mixed = $("body, div, p"); is NOT what I am looking for
In my actual script I've got some <select> inputs assigned to variables. I would like to put them into groups, so say I have a <select> which has "FRUIT" and another one that has "VEGETABLES", I could put them both into a jquery variable called "PRODUCE". Then if I need to perform anything on both of the two, I use produce instead.
...This might just be a stupid way to do things, though.
Perhaps you're looking for .add()?
$mixed = $body.add($div).add($p);
For me, it works fine in jQuery 1.10.2 to simply combine the elements in an array literal before passing into the jQuery constructor: $mixed = $([$body, $div, $p]);
I too was looking for something like this. In my case I had some objects passed into a common function and some created in memory and I wanted to apply the same click event to all of the objects. In the end I went with James's add solution above but thought I would share another option.
If you put the objects into an array you can use the each iterator to perform an action on them.
[$body, $div, $p].each(function(i,e) { e.DoSomething(); });
This syntax is longer and you don't get a reusable $mixed object, but there may be some scenarios where this is useful.
Related
Developers I know tend to call the same JQuery selectors over and over instead of storing the result in a variable. They are consistent with this approach.
For example, they do this:
var propName = $(this).attr('data-inv-name');
var propValue = $(this).attr('data-inv-value');
Instead of this:
var current = $(this);
var propName = current.attr('data-inv-name');
var propValue = current.attr('data-inv-value');
The latter approach feels correct to me but maybe I'm missing something. This is a simple example, but I've seen $(this) repeated dozens of times in the same function.
What is the best practice for development with JQuery? Call selectors repeatedly or store in a variable?
The shown analysis is a micro optimization. Using $(this) repeatedly versus storing $(this) in a variable and reusing it will not cause a significant hit to performance.
The times you really want to store the result is when there is an actual selector in there. The only hit you are taking by repeatedly calling $(this) is calling the jQuery constructor function which is very lightweight.
So in this instance go with what reads better. If there really is a dozen occurrences of $(this) in a row, then there should have either been some storing of the variable as indicated, or more likely there was an opportunity to take advantage of chaining which was missed.
If I'm going to use the same selector more than twice I always create a variable. The one change I would recommend is using $ before your variable name to signify that it is a jQuery object
var $current = $(this);
var propName = $current.attr('data-inv-name');
var propValue = $current.attr('data-inv-value');
In theory selecting the component many times demands more process then using one you already have...
If you don't have too many selectors in your page the diference will be almost null (I guess this is the more commom case)... Then you can think about what makes it more readable or easy to modify...
Sometimes you use the same element in a dozen of lines, in this case I prefer to assign this to a variable because when the element change I will need to change just one line (the line I assigned the variable)...
I have been reading on best practices and I have come across this one:
Dont do this:
$("#element .child").hide()
Do this:
$("#element").find('.child').hide()
Now my question is what if i want to hide/show the .child element multiple times, should I declare it like this:
var spinner = $("#element").find('.child');
spinner.hide();
or do I just keep calling $("#element").find('.child').hide()
Should I declare it like this:
var spinner = $("#element").find('.child');
spinner.hide();
Yes. You should do exactly that since it will obviate the need for multiple dom queries.
One common best practice though, so you can easily keep track of which variables are jQuery objects and which are not, is to prefix your variable with $
var $spinner = $("#element").find('.child');
$spinner.hide();
Yes, create the spinner variable. That way the jQuery constructor/function won't be executed each time, you can reuse the once created objects. The memory overhead is negligible.
That's entirely depending of your problem, if you need to use the same element for multiples purposes in different function, the best options will be to save it into a variable, never the less if you only need once work with chaining of events
Yes, you should always try to keep your selections low, which means that you should save every element selection in a variable that you need more then once.
Try to avoid single DOM operations, also. Let me provide an example:
jQuery('#test').addClass('hide');
jQuery('#check').addClass('hide');
This will add the class "hide" to elements with the id "#test" or "#check". You can apply many jQuery functions like .addClass on element collections also, which will reduce overhead (instead for example iterating over an array / collection with jQuery.each()).
// Select both ids within one query
jQuery('#test, #check').addClass('hide');
This can lead to a huge performance boost if you are really working with the DOM, like adding options to a select box. I've put up a little benchmark on jsfiddle: http://jsfiddle.net/rrgNZ/2/
I have a jquery object being passed to my function. In the function I get to one of the sibling. Now how do I apply the .hover to both the objects in one call.
Thanks
Not sure I know exactly what you want to achieve, but something like this?
myObject.siblings('selector').andSelf().addClass('hover');
The selector depends on how you want to find your sibling. You may want to use something like next('selector') or prev('selector'), rather than siblings().
Update
If the second object is not something that can be chained off of the first object, by a simple selector (which you should be able to do if it's a sibling), there's a more general solution.
var jq1 = $('any set of elements');
var jq2 = $('any other set of elements');
var all = jq1.add(jq2);
This way, regardless of how you find jq1 or jq2, they'll be combined into the variable all. From here you can do
all.addClass('hover');
or
all.click();
Working example
Here's a snippet of the start of my code:
var myUpload = $("#upload_link").upload({bla bla bla
Basically what I'm trying to do is make the same call with a few different ID's...
I would have assumed this would work but it doesn't:
var myUpload = $("#upload_link,#upload_link2,#upload_link3").upload({
Any ideas?
Try this:
$("#upload_link,#upload_link2,#upload_link3").each(function(){
$(this).upload({
//whateveryouwant
});
});
If you give each of these instances a class you can use
$('.yourClass').upload()
You can use multiple id's the way you wrote:
$('#upload_link, #upload_link2, #upload_link3')
However, that doesn't mean that those ids exist within the DOM when you've executed your code. It also doesn't mean that upload is a legitimate function. It also doesn't mean that upload has been built in a way that allows for multiple elements in a selection.
upload is a custom jQuery plugin, so you'll have to show what's going on with upload for us to be able to help you.
Make sure upload plugin implements this.each in it so that it will execute the logic for all the matching elements. It should ideally work
$("#upload_link,#upload_link2,#upload_link3").upload(function(){ });
If all your elements starting with upload_ in its id have the same purpose or syntax you could try and use the following:
$("*[id^='upload_']").each(function() {
$(this).upload()
});
This way you don't have to specify every single element in the selector.
it should. Typically that's how you do multiple selectors. Otherwise it may not like you trying to assign the return values of three uploads to the same var.
I would suggest using .each or maybe push the returns to an array rather than assigning them to that value.
That should work, you may need a space after the commas.
Also, the function you call afterwards must support an array of objects, and not just a singleton object.
I can imagine the correct answer to this based on theory, but I'm just looking for some confirmation. I'm wondering what the most efficient way to re-use a jQuery-selected element is. For example:
$('#my_div').css('background','red');
//some other code
$('#my_div').attr('name','Red Div');
vs.
myDiv = $('#my_div');
myDiv.css('background','red');
//some other code
myDiv.attr('name','Red Div');
I assume the second example is more efficient because the element #my_div doesn't have to get found more than once. Is that correct?
Similarly, is it more efficient to first save $(this) in a varaible, such as 'obj', and then reuse 'obj' rather than using $(this) over and over? In this case, jQuery isn't being forced to find an element over and over again, but it IS being forced to convert this to a jQuery object [$(this)]. So as a general rule of thumb, should a jQuery object ALWAYS be stored in a variable if it will be used more than once?
You should write your code such that you limit the number of DOM traversals.
When you write something like this:
$('#my_div').css('background','red');
//some other code
$('#my_div').attr('name','Red Div');
You are finding #my_div twice, which is inefficient.
You can improve this either by assigning the result of a selector (i.e. var x = $('.something')) and manipulate the variable x, or you can chain your method calls like this:
$('#my_div').css('background','red').attr('name','Red Div');
You'll see the above code used a lot, because you're finding the element once. The css() method will apply a CSS style and return the actual result of $('#my_div'), so you can invoke another method, in this case attr().
My preferred way of handling the re-use of selectors is to store them as a variable, and wrap my stuff in a closure.
if you're using jQuery selector (like $('#element')), then yes, you should always store your results.
if you're using object and wrapping it in jQuery (like $(this)), it's not necessary, because jQuery doesn't need to search for that element again.
One thing that I find is generally overlooked is just how powerful jQuery chains are. It may not be so noticeable, but since jQuery caches your wrapped elements within a chain, you can modify elements, go into a more specific subset, modify, then go back up into a a general superset without much overhead.
I expect something like (pardon the example)
$('#myDiv')
.addClass('processing')
.find('#myInput')
.hide('slow')
.end()
.removeClass('processing')
;
to be better performance-wise than even
var $myDiv = $('#myDiv').addClass('processing');
var $myInput = $('#myDiv #myInput').hide('slow');
$myDiv.removeClass('processing');
This also holds for applying the jQuery function to elements returned in an event handler. Try to avoid applying $(...) too many times, because this is slow. Instead create a variable that contains the result of $(...). Good practice is to start the variable with a $, which gives a hint about the jQuery object inside the variable.
$('a').click(function(){
var $this = $(this);
$this.addClass("clicked");
$this.attr("clicked", true);
});