6

What I mean is how does JavaScript store DOM elements when you do something like:

var foo = document.getElementsByTagName('p');

what does foo become? an array of objects? and how can I add more elements to that variable, for example:

var bar = document.form[0].getElementsByTagName('input'); // 5 elements
var foo = document.form[1].getElementsByTagName('input'); // 4 elements

bar =+ foo;

for (i=0;i<bar.length;i++){
console.log(bar.value); // 9 logged values
}

Is it possible to add more elements of the same type to a variable that already has elements in it? Do I have to loop trough all elements in the variable I want to add and "push" them in the variable I want all the data in?

3
  • use getElementsByTagName() instead of getElementsByName()
    – Givi
    Commented Jun 19, 2013 at 21:40
  • What would be the difference between using TagName and Name? Commented Jun 19, 2013 at 21:44
  • 1
    The getElementsByTagName() method accesses all elements with the specified tagname, and getElementsByName() method accesses all elements with the specified name. tagname is html element tag name such as <div> or <p> and name is attribute such as <div name="somename">
    – Givi
    Commented Jun 19, 2013 at 21:46

3 Answers 3

10

getElementsByTagName (and similar methods such as getElementsByName, getElementsByClassName, etc) returns a NodeList (or HTMLCollection, depending on the browser apparently, see also Difference between HTMLCollection, NodeLists, and arrays of objects).

Even though it is an array-like object, i.e. it has numeric properties and a .length property, you cannot add new elements to it.

In order to modify the NodeList, you have to convert it to a regular array. This can easily be achieved with the array method .slice and at the same time you can merge both lists with .concat:

bar = Array.prototype.slice.call(bar).concat(Array.prototype.slice(foo));

This works because most native array methods are defined in such a way that the argument does not have to be an actually array, but an array-like object.

The noteworthy differences between a NodeList and the final array are:

  • The array is not live anymore, i.e. the collection is not automatically updated when new DOM nodes are added.
  • The elements in the final (merged) array won't necessarily be in document order.
7
  • Thanks for the wonderful answer, the example, the links for further reference and answering all my questions! Commented Jun 20, 2013 at 13:20
  • Hi Felix I thought that you could may be help me with a question that I haven't got any answers only low views. I would greatly apreciate it! Difference between contentDocument and contentWindow Commented Jun 25, 2013 at 16:51
  • Note that for IE<9 Array.prototype.slice.call(bar) does not work it will output the error: "JScript Object Expected" for a workaround loop through all elements in each NodeList and add them to an array a complete example can be found in [[function].apply() causing “JScript object expected” error in IE](stackoverflow.com/q/11112950/1079232) Commented Aug 2, 2013 at 14:18
  • @SamuelLopez: Try to pass 0 as second argument: Array.prototype.slice.call(bar, 0). Commented Aug 2, 2013 at 14:19
  • So IE supports the method but it expects 2 arguments? I found the question above while searching for information on the error and found that example. Commented Aug 2, 2013 at 14:22
1

bar =+ foo;

this works only for string concatenation and it would be bar+= foo

but both bar and foo here are DOM objects. so if you want to add elements of the same type u can create an array.

e.g.,

var myArray =[]
myArray.push(foo);
myArray.push(bar);
2
  • Your example would create an array with two values, both of them would be NodeLists, not elements. It would not merge both NodeLists Commented Jun 19, 2013 at 21:59
  • well he mentioned he wanted to add elements to a variable which already had elements to it
    – Gokul Kav
    Commented Jun 19, 2013 at 23:30
-4

foo becomes the function. So you wouldn't be able to add foo to bar because that doesn't make sense. It would be like trying to do:

document.form[0].getElementsByName('input') document.form[1].getElementsByName('input');

You could have multiple elements in a single array. I'd find that to be the simplest way to reach your solution.

4
  • 5
    foo becomes node list not function
    – Givi
    Commented Jun 19, 2013 at 21:42
  • ooo I get it now, is there any way then to store elements in a variable so later you can add more elements to the variable? would using TagName change something like @Givi said? Commented Jun 19, 2013 at 21:45
  • @SamuelLopez Felix Kling provided the perfect answer to your question
    – Givi
    Commented Jun 19, 2013 at 21:49
  • @Givi yes he did I just got involved with another task and didn't have time to select it as the response :s I did upvote it though and it is perfect! Commented Jun 20, 2013 at 13:18

Not the answer you're looking for? Browse other questions tagged or ask your own question.