73

Is it possible to merge several jQuery DOM objects into one array and call jQuery methods on all of them?

F.ex:

<button>one</button>
<h3>two</h3>

<script>

var btn = $('button');
var h3 = $('h3');

$([btn,h3]).hide();

</script>

This doesn't work. I know I can use the 'button,h3' selector here but in some cases I already have several jQuery DOM elements and I need to merge them so I can call jQuery prototypes on all of them.

something like:

$.merge([btn,h3]).hide();

would work. Any ideas?

UPDATE:

Solved it. You can do it like this:

$.fn.add.call(btn,h3);

I'm going to accept the add() suggestion as for pointing me in the right direction.

hippietrail
  • 15,848
  • 18
  • 99
  • 158
David Hellsing
  • 106,495
  • 44
  • 176
  • 212
  • 5
    @David, why the bizarre use of `call`? `btn.add(h3)` works... – nickf Dec 10 '09 at 15:53
  • 1
    Because I do not know the first object, so I can't chain. Apply() would be even better, so I can send an array using $.fn.add.apply(arr.shift(),arr); – David Hellsing Dec 10 '09 at 16:21
  • 1
    is there a way to add more than 2 objects ? – vsync Mar 31 '10 at 07:41
  • 12
    If you don't know the first object, you can avoid using `call` by chaining off an empty jQuery object: `$().add(btn).add(h3)`. IMO, this is a much better way to use `$.add`. – Matt Ball Aug 19 '10 at 18:58
  • `$.fn.add.call()` will fail if its first argument is not a jQuery object. – dbkaplun Jul 24 '12 at 19:28
  • 1
    is this basically a duplicate of http://stackoverflow.com/questions/323955/how-to-combine-two-jquery-results – jrz Aug 28 '14 at 21:43
  • Weird, but nice way to use add in my opinion, as far as you don't want to chain .add() – Charly Oct 23 '17 at 14:50
  • Does this answer your question? [How to combine two jQuery results](https://stackoverflow.com/questions/323955/how-to-combine-two-jquery-results) – clickbait Mar 27 '22 at 19:07

6 Answers6

33

.add() does exactly what you're after.

h3.add(btn).hide();

If you wanted to make it a little more convenient for yourself, with a "merge" function like in your question, this could be added easily:

$.merge = function(objs) {
    var ret = objs.shift();
    while (objs.length) {
        ret = ret.add(objs.shift());
    }
    return ret;
};

$.merge([h3, btn]).hide()
Alois Christen
  • 543
  • 3
  • 14
nickf
  • 537,072
  • 198
  • 649
  • 721
  • 10
    JQuery now has a merge function so something other than $.merge should be used. – Tom Hubbard Mar 09 '11 at 15:48
  • 5
    If I'm not mistaken, `jQuery.Add` method causes a new `jQuery` object to be produced instead of modifying the original object on which the method is called. Isn't it `ret = ret.Add(objs.shift());`? – Oybek Oct 16 '14 at 17:31
8

$.map can flatten arrays:

function merge(array_of_jquery_objects) {
    return $($.map(array_of_jquery_objects, function(el) {
        return el.get();
    }));
}
Tgr
  • 27,442
  • 12
  • 81
  • 118
5
$(btn).add(h3).hide();

Not sure if it works though, documentation for add doesn't mention haivng the jQuery object as a parameter but only a list of elements, so if that doesn't work this should:

$(btn).add(h3.get()).hide();
TWiStErRob
  • 44,762
  • 26
  • 170
  • 254
Svante Svenson
  • 12,315
  • 4
  • 41
  • 45
3

Get some jQuery objects:

var x = $('script'),
    y = $('b'),
    z = $('body');

Create a new jQuery object, containing all the other objects:

$( $.map([x,y,z], a => [...a]) )

Demo: (open your browser's console)

var x = $('script'),
    y = $('b'),
    z = $('body');

// step 1
// put all the jQuery objects in an Array to prepare for step 2
var step1 = [x,y,z];
console.log(step1)

// using jQuery.map and a callback, extract  the actual selector from the iterable 
// array item and return it, so the result would be a simple array of DOM nodes
// http://jqapi.com/#p=jQuery.map
var step2 = $.map(step1, a => [...$.makeArray(a)])
console.log(step2);

// convert the javascript Array into jQuery Object (which contains all the nodes)
var step3 = $( step2 )
console.log(step3);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<b></b>
vsync
  • 118,978
  • 58
  • 307
  • 400
2

Use this one.

<script>

var btn = $('button')[0];
var h3 = $('h3')[0];

$([btn,h3]).hide();

</script>
Lakin Mohapatra
  • 1,097
  • 11
  • 22
  • 1
    This will only merge the very first element in each set, therefor it is far from an optimal answer. only good in very specific cases. – vsync Oct 24 '16 at 16:39
1

To take the use of add a little farther, you could use reduce with it for another approach:

var $mySelector1 = $('.selector1');
var $mySelector2 = $('.selector2');
var $mySelector3 = $('.selector3');
var selectorArray = [$mySelector1,$mySelector2,$mySelector3];
var $combinedSelector = selectorArray.reduce(function(total, current){
    return $(total).add(current)
});
samnau
  • 683
  • 7
  • 7