0

My specific issue is that I need to get all elements in one class into a div. My attempt was:

myElement = document.getElementsByClassName("a_random_class");
document.getElementByID("unique_ID").innerHTML = myElement.innerHTML;

Yet it didn't work. Now I'm not sure how can I achieve this...

Optional: The general issue is that I'm working with a PHP script that has no template engine which makes it very difficult to modify the layout, having to change multiple files... So my idea was to use Javascript in order to render some elements the way I need and so being able to give them the style I need... Is that a good idea? are there alternatives?

Thank you very much for your time.

Henrique Barcelos
  • 7,670
  • 1
  • 41
  • 66

1 Answers1

3

getElementsByClassName returns an HTMLCollection (it used to be a NodeList; let's just call it a list), not just one element, and that list doesn't have an innerHTML property.

If you want to copy the elements with the class, you can do it in a loop wiht cloneNode:

setTimeout(function() {
  var element = document.getElementById("unique_ID");
  element.innerHTML = "";
  Array.prototype.forEach.call(document.querySelectorAll(".a_random_class"), function(e) {
    element.appendChild(e.cloneNode(true));
  });
}, 300);
#unique_ID {
  border: 1px solid blue;
}
<div id="unique_ID"></div>
<div class="a_random_class">a</div>
<div class="a_random_class">b</div>
<div class="a_random_class">c</div>
<div class="a_random_class">d</div>
<div class="a_random_class">e</div>
<div class="a_random_class">f</div>

I've used querySelectorAll rather than getElementsByClassName for two reasons:

  1. getElementsByClassName returns a live list, which makes things awkward when you're copying/moving nodes, because the thing you're looping over keeps changing. We could turn it into an array like this, though:

    var arr = Array.prototype.slice.call(document.getElementsByClassName('a_random_name'));
    

    ...and then use arr.

  2. querySelectorAll is better supported than getElementsByClassName (IE8, for instance, has querySelectorAll but not getElementsByClassName).

Note that that uses the Array#forEach function even though a NodeList isn't an array. (More about that here, scroll down to "For Array-Like Objects".) (If you need to support IE8, you'll need to shim/polyfill it or replace it with a plain for loop.)

Or if you want to move them, just don't use cloneNode:

setTimeout(function() {
  var element = document.getElementById("unique_ID");
  element.innerHTML = "";
  Array.prototype.forEach.call(document.querySelectorAll(".a_random_class"), function(e) {
    element.appendChild(e);
  });
}, 300);
#unique_ID {
  border: 1px solid blue;
}
<div id="unique_ID"></div>
<div class="a_random_class">a</div>
<div class="a_random_class">b</div>
<div class="a_random_class">c</div>
<div class="a_random_class">d</div>
<div class="a_random_class">e</div>
<div class="a_random_class">f</div>
Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thank you very much @T.J.Crowder ! I highly appreciate your time spent on it. May I ask you (if not too much trouble) how can I add a new class to the element(s) copied by getElementsByClassName? is that possible? – Daniel Felipe Jun 02 '15 at 18:20
  • @Oriol: Ack! The one I ran across was from 28 May...2011, not 2015! Thanks for the latest. – T.J. Crowder Jun 02 '15 at 18:21
  • @DanielFelipe: Store the result of `cloneNode`, then do `.className += " the-new-class";` on it (note the leading space) to add another one. (On modern browsers, you could use `classList`, but it's still relatively new.) – T.J. Crowder Jun 02 '15 at 18:23
  • sorry to bother, but I'd like to know how can I add innerHTML within the results of cloneNode. Not only a class, but let's say `` tags to the results... I've tried quitea lot with different positions of innetHTML... `+= "" + stored_variable + "";` but it doesn't work :/ .. I had stored it like this: `var example = element.appendChild(e.cloneNode(true)); example.className += " the-new-class";` – Daniel Felipe Jun 02 '15 at 19:52
  • @DanielFelipe: If you wanted to wrap the element in a `b` tag, your best bet would be `var b = document.createElement('b'); b.appendChild(example); element.appendChild(b);` – T.J. Crowder Jun 02 '15 at 21:25
  • Actually I'd like to wrap html in general, maybe surround with divs, spans, with classes and so on, would that be possible? – Daniel Felipe Jun 02 '15 at 23:19
  • @DanielFelipe: It's all *possible*, you just use DOM methods, `innerHTML`, or `outerHTML`, or a combination. – T.J. Crowder Jun 03 '15 at 06:57