1

I am trying to gather these HTML objects through getElementsByClassName, and push them into a JavaScript array and then I want to create a JavaScript alert to display these names. I’ve been trying this for hours. Am I doing something wrong?

var names = []
var elm = document.getElementsByClassName('name');
names.push(elm);
var arr = names.join();
alert(arr)
<h2>
  List of People:
</h2>

<ul class='people'>
  <li class='name'>
    Clara
  </li>
  <li class='name'>
    James
  </li>
  <li class='name'>
    Sara
  </li>
</ul>
  • 1
    Check out [*Array.from*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from). – RobG Jul 12 '17 at 06:02
  • Possible duplicate of [Most efficient way to convert an HTMLCollection to an Array](https://stackoverflow.com/questions/222841/most-efficient-way-to-convert-an-htmlcollection-to-an-array). `elm` is an `HTMLCollection`. `names.push(elm)` pushes that entire `HTMLCollection` to an array. – Sebastian Simon Jul 12 '17 at 06:02
  • Whilst that question is similar, the answer is outdated. Array.from() is the superior option in a modern JavaScript environment. – David L. Walsh Jul 12 '17 at 06:05
  • @DavidL.Walsh There’s more than one answer there. The second one includes `Array.from` and the spread syntax. – Sebastian Simon Jul 12 '17 at 06:06
  • My apologies. I am new to coding and StackOverflow. – NewbiusCoder Jul 12 '17 at 06:14

3 Answers3

3

getElementsByClassName does not give you the text inside the elements, but the elements themselves.

Also you won't get them as a proper JavaScript array, but a collection of HTMLElements.

Here's what you can do:

var names = []
var elements = document.getElementsByClassName('name');
for(var i=0; i<elements.length; i++) names.push(elements[i].textContent)
var nameList = names.join()
alert(nameList)

Alternatively you may use Array.from and map:

Array.from(elements).map((elem) => elem.textContent)

Note that I'm using elements[i].textContent to get the text inside each element.

geekonaut
  • 5,714
  • 2
  • 28
  • 30
  • You are amazing. I appreciate all of your time and effort. I wish you a beautiful life. – NewbiusCoder Jul 12 '17 at 06:10
  • Or you could use `Array.prototype.map.call(elements, elem=>elem.textContent)`. ;-) – RobG Jul 12 '17 at 06:16
  • You code met my requirements. However, this output comes out with the names on top of each other. How can I make it so it comes out as one line? Your time is greatly appreciated. Thanks. – NewbiusCoder Jul 12 '17 at 06:18
  • Sure. To remove whitespace and linebreaks, you may replace them with nothing: elem.textContent.replace(/\r?\n|\r|\s+/g, '') – geekonaut Jul 12 '17 at 06:22
  • I appreciate your time, however I have no clue what that means. I will attempt to do some research and refer back to your comment in the future. Thank you. – NewbiusCoder Jul 12 '17 at 06:26
  • @geekonaut—I think the OP is talking about the appearance of the result when written to the console, so `.join('')` might be what's required (or not). – RobG Jul 12 '17 at 06:28
  • @RobG Thank you RobG, the .join(' ') removed the commas. The linebreaks are still present. I appreciate your time. – NewbiusCoder Jul 12 '17 at 06:35
  • @geekonaut - I am unable to figure out where to place that code. I am sorry for troubling you so much. I will keep trying. But do you mean elements.textContent.replace(/\r?\n|\r|\s+/g, '')? For I do not have a variable named elem. Thank you. – NewbiusCoder Jul 12 '17 at 06:37
  • You replace this: `for(var i=0; i – geekonaut Jul 12 '17 at 06:40
  • You will not be forgotten @geekonaut. Thank you for all your help. – NewbiusCoder Jul 12 '17 at 06:45
0

Simply Try with querySelectorAll() .Then apply Nodelist#forEach() to iterate the node list .Finally push into array with element or element attribute which you want

var names = []
var elm = document.querySelectorAll('.name').forEach(function(a){
names.push(a.innerHTML);
});

var arr = names.join();
console.log(arr);
alert(arr)
<h2>
  List of People:
</h2>

<ul class='people'>
  <li class='name'>
    Clara
  </li>
  <li class='name'>
    James
  </li>
  <li class='name'>
    Sara
  </li>
</ul>
prasanth
  • 22,145
  • 4
  • 29
  • 53
  • I appreciate your time. Unfortunately I am too new to coding to understand this at the moment. I will look back in the future. However your provided code was unable to create an alert popup. Thank you for your effort! – NewbiusCoder Jul 12 '17 at 06:19
  • The forEach method is only a recent addition to the NodeList spec, and won't be available in all environments. Other array methods (such as map) are missing completely from NodeList. Given the potential confusion, I'd discourage iterating on NodeList and instead simply converting it to an array. – David L. Walsh Jul 12 '17 at 06:20
  • While [*MDN claims*](https://developer.mozilla.org/en-US/docs/Web/API/NodeList) that *forEach* is available on NodeList and HTMLCollection objects, it's not listed in any of the standards or specifications listed in the specifications sections of relevant MDN pages (the [*WHATWG DOM spec*](https://dom.spec.whatwg.org/#old-style-collections) was updated 2 days ago). It is also not widely implemented. – RobG Jul 12 '17 at 06:24
  • @NewbiusCoder i was added with alert comment . – prasanth Jul 12 '17 at 06:27
  • Thank you so much. The code worked. I will slowly try to understand this code. However it came with line breaks and whitespace. I am currently trying to understand "someText = someText.replace(/(\r\n|\n|\r)/gm,"")", but I am having troubles. – NewbiusCoder Jul 12 '17 at 06:33
0

When we call elements by class name it returns array so you have run loop...

List of People:

 <ul class='people'>
 <li class='name'>
   Clara
 </li>
 <li class='name'>
  James
</li>
<li class='name'>
  Sara
</li>

 var names = []
 var elm = document.getElementsByClassName('name');
 for(var i = 0; i < elm.length; i++) {
    names.push(elm[i].innerHTML);
   }
 names.join();
 alert(names);

here is jsfiddle running example https://jsfiddle.net/9pt0hf0s/1/

Muneeb
  • 1,469
  • 16
  • 24