Volt Volt - 1 month ago 8
HTML Question

Javascript Count the amout of a cetain element

I have some javascript that returns a chunk of code, this code contains a mostly random amount of

<li>
elements, a sample output would be:

<li class="shiny-box choice clearfix" data-choice-id="0">
<span class="index">1.</span>
<span class="val ">vīta vītae f.</span>
<span class="marking-icon"></span>
</li>
<li class="shiny-box choice clearfix" data-choice-id="1">
<span class="index">2.</span>
<span class="val ">patria patriae f.</span>
<span class="marking-icon"></span>
</li>
<li class="shiny-box choice clearfix" data-choice-id="2">
<span class="index">3.</span>
<span class="val ">poena poenae f.</span>
<span class="marking-icon"></span>
</li>
<li class="shiny-box choice clearfix" data-choice-id="3">
<span class="index">4.</span>
<span class="val ">fortūna fortūnae f.</span>
<span class="marking-icon"></span>
</li>


I need a way, in vanilla javascript to return in array format, the contents of the
class=val
spans.

An example of the output of this code would be:

var array = ["vīta vītae f.","patria patriae f.","poena poenae f.","fortūna fortūnae f."];


Please keep in mind that there is not always 4
<li>
elements.

Is there any function that could do this?

Answer

If you are starting from a string, you need to first have the browser parse the string into a DOM. You can do that by creating a dummy HTML element, and putting your raw HTML inside it as innerHTML property. Then you will be able to search it using querySelectorAll (or getElementsByClassName, but QSA is more powerful, and doesn't make a live collection, so bonus). When you have a collection of nodes, you can use map function to extract the textContent. NodeList that QSA returns is compatible with map, but doesn't actually have it, so we have to "borrow" it from the array prototype.

Note that you should use textContent and not innerHTML to extract your strings, because if you have "fort&#x016b;na" instead of "fortūna" in your HTML (both of which have the same meaning in HTML, but the first one is encoding-agnostic), innerHTML will give you the former, and textContent will give you the latter.

var rawHTML = '<li class="shiny-box choice clearfix" data-choice-id="0"> <span class="index">1.</span> <span class="val ">vīta vītae f.</span> <span class="marking-icon"></span> </li> <li class="shiny-box choice clearfix" data-choice-id="1"> <span class="index">2.</span> <span class="val ">patria patriae f.</span> <span class="marking-icon"></span> </li> <li class="shiny-box choice clearfix" data-choice-id="2"> <span class="index">3.</span> <span class="val ">poena poenae f.</span> <span class="marking-icon"></span> </li> <li class="shiny-box choice clearfix" data-choice-id="3"> <span class="index">4.</span> <span class="val ">fortūna fortūnae f.</span> <span class="marking-icon"></span> </li>';

var root = document.createElement('div');
root.innerHTML = rawHTML;
var valNodes = root.querySelectorAll('.val');
var texts = Array.prototype.map.call(valNodes, node => node.textContent);
console.log(texts);