结合getElementsByTagName和getElementsByClassName

时间:2015-03-25 11:28:31

标签: javascript html

我正在尝试将getElementsByTagName和getElementsByClassName结合起来缩小搜索范围并计算结果节点,但第二次搜索总是导致长度为0,我不知道为什么。

<!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>

我知道我可以使用querySelectorAll,就像我已注释掉的那一行一样,但我想了解为什么第一个解决方案无效,以及我可以做些什么来修复它。

谢谢!

3 个答案:

答案 0 :(得分:4)

第一个例子的问题是:

pElements[i].getElementsByClassName("content")

搜索p元素的子元素。但由于它实际上是在同一个元素上,所以找不到它们。

W3C reference: &#34; getElementsByClassName()方法返回具有指定类名&#34的元素子元素的集合;

编辑:要查找p元素是否具有内容类,而不是getElementsByClassName(),您可以使用

pElements[i].classList.contains("content")

如果元素具有类,则返回true。 Reference

EDIT2:更加向后兼容的方式是获取className属性,将其拆分为空格并迭代数组以查看该类是否存在。

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
}

答案 1 :(得分:2)

您无法合并getElementsByTagNamegetElementsByClassName。因为正如@juunas所提到的,pElements现在由包含所有<p>元素的数组的结果组成。

当您使用getElementsByClassNamepElements[i].getElementsByClassName("content")应用于此结果集时,会搜索pElements的子元素。

暗示性结果: 使用getAttribute()功能检查class中每个元素的pElements,例如,

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);

答案 2 :(得分:0)

这是因为你的p元素没有任何带有“content”类的元素。 p元素本身就有这个类,所以你找不到它,0是正确的。

更改

<p class="content">Stuff2</p>

<p><span class="content">Stuff2</span></p>

结果你会得到1。