Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to concatenate an HTMLCollection with an array?

Tags:

javascript

It may sounds like a silly question but

var arr1 = ['1', '2'];
var arr2 = ['3', '4'];
console.log(arr1.concat(arr2));

will output ["1", "2", "3", "4"]

But

var arr1 = ['1', '2'];
console.log(
  arr1.concat(document.getElementsByTagName('h1'))
);

will output ["1", "2", HTMLCollection[2]]

How do I concatenate the html collection with an array ?

like image 658
vdegenne Avatar asked Feb 10 '17 09:02

vdegenne


People also ask

How do I turn an HTMLCollection into an array?

One way to convert an HTMLCollection to a JavaScript array is to use the slice method. We get divs by call querySelector to select all the divs in the HTML. We just call slice with divs and it'll return the div element objects in an array. We call slice on an empty array and pass in the divs HTML.

Can you use array methods on an HTMLCollection?

Array. from() method will create a new Array instance from an array-like or iterable object. So it can be used both on NodeList and HTMLCollection . This is a clear and straightforward method to create an Array , and not only from NodeList or HTMLCollection .

Is an HTMLCollection an array?

An HTMLCollection is not an Array! An HTMLCollection may look like an array, but it is not. You can loop through an HTMLCollection and refer to its elements with an index. But you cannot use Array methods like push(), pop(), or join() on an HTMLCollection.


3 Answers

You need to convert the HTMLCollection into an array. The best way of doing this in modern Javascript is Array.from. This converts any array-like object (or other iterable value) into a real Javascript array.

arr1.concat(Array.from(document.getElementsByTagName('h1')))
like image 149
lonesomeday Avatar answered Oct 29 '22 01:10

lonesomeday


You can use push.apply, like so:

var arr1 = ['1', '2'];
arr1.push.apply(arr1, document.getElementsByTagName('h1'));
console.log(arr1);
<h1>x</h1>
<h1>y</h1>

And in ES2015+ (aka ES6+), you can use push with spread notation:

var arr1 = ['1', '2'];
arr1.push(...document.getElementsByTagName('h1'));
console.log(arr1);
<h1>x</h1>
<h1>y</h1>

Note that in both cases, this is different from concat in that it avoids creating a new array (it just modifies the original one referenced by arr1). Whether that difference is a good thing (not creating unnecessary objects) or a bad thing (I wanted a new array!) depends on your use case. :-)

like image 37
T.J. Crowder Avatar answered Oct 29 '22 02:10

T.J. Crowder


You can use Array.from, however it's fairly new so may not be supported by all the browsers you need. Some alternatives, the last of which will be supported by all browsers in use:

  1. Spread syntax, which is new, only supported by the most recent browsers and no version of IE
  2. Array.prototype.slice.call to convert the NodeList to an array, but will fail in IE 8 where passing host objects to built–in methods as this fails
  3. Array.prototype.map.call to convert to an array. Avoids the IE 8 issue as map will need to be polyfilled (but then you might as well use a polyfill for Array.from and be done with it)
  4. Use array.concat.apply and pass the NodeList as an argument, no need for polyfills for old browsers

Runnable snippet below.

var arr = [0,1];
var divs = document.querySelectorAll('div');

// Use spread syntax, pretty new though
var spread = arr.concat(...divs);
console.log('Spread\n' + spread.join('\n'));

// Convert to array using slice, then concat
var sliced = Array.prototype.slice.call(divs).concat(arr);
console.log('Sliced\n' + sliced.join('\n'));

// Convert to array using map, then concat
var mapped = Array.prototype.map.call(divs, function(div){return div}).concat(arr);
console.log('Mapped\n' + mapped.join('\n'));

// Call concat with apply directly using concat
var conned = arr.concat.apply(arr, divs);
console.log('Conned\n' + conned.join('\n'));
<div>div1</div>
<div>div2</div>
like image 42
RobG Avatar answered Oct 29 '22 02:10

RobG