Is it possible to use multiple variables instead of selectors in jQuery

Jquery

Jquery Problem Overview


I know that it's faster to do the following:

var $header = $("#header");
$header.css({color:"#ff0000"});
$header.find("a").addClass("foo");

Instead of:

$("#header").css({color:"#ff0000"});
$("#header a").addClass("foo");

Because jQuery doesn't need to find the elements again in the DOM as we have direct reference to them.

Let's say that I have this:

var $header_elements = $("#header li");
var $footer_elements = $("#footer li");

And I use both individually for a few jQuery manipulations. But then, I need to do something on both. Using selector, I would do this:

$("#header li, #footer li").css({color:"#ff0000"});

But then, the DOM needs to be parsed again to find matching elements. Is there a way to use my previously declared variables instead of a new selector? Something like the following (which is not working, I know, it's to give an idea of what I'm looking for):

$($header_elements + $footer_elements).css({color:"#ff0000"});

I think that the selector returns some kind of array or object. What I'm looking for is a way to merge those. Anyone know if this is possible and how to do it?

Thanks for your help!

Jquery Solutions


Solution 1 - Jquery

Just use the add method:

$header_elements.add($footer_elements).css({color:'#ff0000'});

> Given a jQuery object that represents > a set of DOM elements, the .add() > method constructs a new jQuery object > from the union of those elements and > the ones passed into the method. The > argument to .add() can be pretty much > anything that $() accepts, including a > jQuery selector expression, references > to DOM elements, or an HTML snippet.

Solution 2 - Jquery

I found the solutions a few minutes after posting this. For those who are wondering, here it is:

$.merge($header_elements, $footer_elements).css({color:"#ff0000"});

Is it faster? I don't know yet, I'll need to run some tests to find out.

EDIT:

I tested it with JS Fiddle here : http://jsfiddle.net/bgLfz/1/

I tested using selector each time, variable for both selector, variables with $.merge() and using .add(). Each test was run 1000 times.

Results on my side are as follow (from faster to slower):

  1. Using $.merge() (average of 7ms)
  2. Using both variable one after the other (average of 10ms but the code needs to be duplicated)
  3. Using .add() (average of 16ms)
  4. Using selectors each time (average of 295ms)

Solution 3 - Jquery

You can use add or merge method:
Add

$header_elements.add($footer_elements).css({color:'#f00'});

merge

$.merge($header_elements, $footer_elements).css({color:"#f00"});

Both work, but add is more performant. enter image description here Source: http://jsperf.com/add-vs-merge

Credit: I upvoted @GenericTypeTea and @Gabriel answers, did a summary of both, compared them and here is the result.

Solution 4 - Jquery

Pass an array of references:

$([$header_elements, $footer_elements]).css({color:"#ff0000"});

Solution 5 - Jquery

It does not matter performance wise wether you'll do something like (even if it worked):

$($header_elements + $footer_elements).css({color:"#ff0000"});

or do them separately:

$($header_elements).css({color:"#ff0000"});
$($footer_elements).css({color:"#ff0000"});

as jquery will internally go through the supplied arguments using each().

If the principle is more DRY inspired, than performance wise, you can create a function:

function makeThemRed( el ) {el.css({color:"#ff0000"})}

and then

makeThemRed($header_elements);
makeThemRed($footer_elements);

or even:

function makeThemRed() 
{
   var l=arguments.length,
       o=0;
   while (o<l) {
       arguments[o++].css({color:"#ff0000"})
    }
}

and then

 makeThemRed($header_elements, $footer_elements); //any number of parameters

Solution 6 - Jquery

The thing with using 'merge' is that it's limited to just two selectors, and using 'add' will be so messy if it's more than two, so if it's more than two, you should use 'each' like this:

$([selector1, selector2, selector3, .....etc]).each(function(){
    // your code here
});

Solution 7 - Jquery

To keep the code simple and prevent code duplication I used a forEach loop.

var $header_items = $("#header li");
var $footer_items = $("#footer li");

[$header_items, $footer_items].forEach(function($blockItems){
    // do logic here
    $blockItems.css('color', 'red');
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header">
    <h1>Header</h1>
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
        <li>Item 5</li>
    </ul>
</div>
<div id="footer">
    <h1>Footer</h1>
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
        <li>Item 5</li>
    </ul>
</div>

Solution 8 - Jquery

You could always set all of the elements to one variable:

var $lis = $('#header li, #footer li');
$($lis).css({color:"#ff0000"});

Solution 9 - Jquery

Use ES6 template literals for multiple variables as selectors:

$(`${$header_elements}, ${$footer_elements}`).css('color','#ff0000');

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGabrielView Question on Stackoverflow
Solution 1 - Jquerydjdd87View Answer on Stackoverflow
Solution 2 - JqueryGabrielView Answer on Stackoverflow
Solution 3 - JquerySimon ArnoldView Answer on Stackoverflow
Solution 4 - JqueryAnpherView Answer on Stackoverflow
Solution 5 - JqueryraverenView Answer on Stackoverflow
Solution 6 - JqueryHazem_MView Answer on Stackoverflow
Solution 7 - JqueryLasithdsView Answer on Stackoverflow
Solution 8 - JqueryBrian RayView Answer on Stackoverflow
Solution 9 - JquerykwyjibearView Answer on Stackoverflow