Reputation: 3
I'm trying to combine getElementsByTagName and getElementsByClassName to narrow a search down and count the resulting nodes, but the second search always results in a length of 0, and I've no idea why.
<!DOCTYPE html>
<html>
<head></head>
<body>
<p>Stuff</p>
<p class="content">Stuff2</p>
<p>Stuff</p>
<p class="content">Stuff2</p>
<script type="text/javascript">
pElements = document.getElementsByTagName("p");
console.log(pElements);
for(i = 0; i < pElements.length; i++) {
console.log(pElements[i].getElementsByClassName("content").length);
}
//console.log(document.querySelectorAll('p.content').length);
</script>
</body>
</html>
I know I can use querySelectorAll for this like the line I have commented out, but I'd like to understand why the first solution isn't working, and what I can do to fix it.
Thanks!
Upvotes: 0
Views: 7428
Reputation: 21
You can NOT combine getElementsByTagName
and getElementsByClassName
. Because as mentioned by @juunas, pElements
now consists of the result consisting of an array of all the <p>
elements.
And when you apply the getElementsByClassName
to this result-set, using pElements[i].getElementsByClassName("content")
, it searches in the child elements of pElements
.
Suggestive Result :
Use the getAttribute()
function to check the class
of each element in pElements
, like,
pElements = document.getElementsByTagName("p");
console.log(pElements);
for(var i = 0, j = 0; i < pElements.length; i++) {
if (pElements[i].getAttribute("class") === "content") {
j++;
}
}
console.log("Length of the resulting nodes: ", j);
Upvotes: 2
Reputation: 58733
The problem with the first example is that:
pElements[i].getElementsByClassName("content")
searches for children of the p element. But since it is actually on the same element, they are not found.
W3C reference: "The getElementsByClassName() method returns a collection of an element's child elements with the specified class name"
EDIT: To find if a p element has the content class, instead of getElementsByClassName(), you could use
pElements[i].classList.contains("content")
which will return true if the element has the class. Reference
EDIT2: A more backwards-compatible way would be to get the className
property, split it on spaces and iterate the array to see if the class is there.
var names = pElements[i].className.split(" ");
var found = false;
for(var i = 0; i < names.length; i++){
if(names[i] === "content"){
found = true;
break;
}
}
if(found){
//Your code here
}
Upvotes: 4
Reputation: 1583
It's because your p-elements dont have any elements with the class "content". The p-elements itself have this class, so you cant find it and 0 is correct.
Change
<p class="content">Stuff2</p>
To
<p><span class="content">Stuff2</span></p>
And you will get 1 as the result.
Upvotes: 0