im very new to javascript and probably thats a silly question. What I am trying to achieve is to loop through rows of a "table", get the innerHTML of specific child nodes and multiply them together.
The html looks like this:
<div >
...
<div >
<div >
<span >5</span>
</div>
</div>
<div >
<span >30</span>
</div>
...
</div>
<div >
...
<div >
<div >
<span >2</span>
</div>
</div>
<div >
<span >30</span>
</div>
...
</div>
To be specific: I want to get both the values inside the'countChild' and the 'valueChild'. In this example those are 5 and 30 for the first row and for the second row its 2 and 30. Then perform a muiltiplication.
What I tried to do is to get all the parent nodes and then iterating through them to get the child nodes.
const parents = document.getElementsByClassName('parent');
for(var row in parents) {
var count = row.getElementsByClassName('countChild').lastChild.innerHTML;
var value = row.getElementsByClassName('valueChild').lastChild.innerHTML;
....
}
However the debugger already throws an error when im trying to get the childs. The error message is row.getElemenstByClassName is not a function. I guess the collection cannot be used like this and my understanding of how to use js to get information from the document is wrong.
Edit: This is what the tree looks like
<div >
<div >
<div >
<div >
<span >30</span>
</div>
</div>
</div>
<div >
<span >5</span>
</div>
</div>
CodePudding user response:
You should access parents
like an array (not really array but you can cast it to one). Btw, I encourage you to use querySelectorAll
and querySelector
instead of getElementsByClassName
const parents = document.querySelectorAll(".parent")
parents.forEach(function(row) {
var countChild = row.querySelector(".countChild")
var valueChild = row.querySelector(".valueChild")
var count = countChild ? countChild.innerText : 0
var value = valueChild ? valueChild.innerText : 0
console.log(count, value, count * value)
})
<div >
...
<div >
<div >
<span >5</span>
</div>
</div>
<div >
<span >30</span>
</div>
...
</div>
<div >
...
<div >
<div >
<span >2</span>
</div>
</div>
<div >
<span >30</span>
</div>
...
</div>
Edit: I'm using querySelector instead of getElementsByClassName, and checking if child exists before accessing its innerText property.
Edit: here's a function to get all text nodes under a specific node. Then you can combine them and trim the result to get the value you want.
function textNodesUnder(node) {
var all = [];
for (node = node.firstChild; node; node = node.nextSibling) {
if (node.nodeType == 3) {
all.push(node);
} else {
all = all.concat(this.textNodesUnder(node));
}
}
return all;
}
var nodes = textNodesUnder(document.querySelector(".listing-entry"))
var texts = nodes.map(item => item.nodeValue.trim())
console.log(texts)
<div >
<div >
<div >
<div >
<span >30</span>
</div>
</div>
</div>
<div >
<span >5</span>
</div>
</div>