这是我被问到的问题,我想知道该怎么做或者它是否是一个技巧问题。我一直只使用JavaScript,所以我不太确定。
假设您有一个包含大量内容的网页。 不使用任何库或getElementsByClassName ,遍历DOM并查找具有特定类名的所有元素。
示例HTML
<body>
<div>
<div class='myTarget'>
Target exists here
</div>
</div>
<div>
<table>
<tbody>
<tr> <td class='myTarget'> Target exists here </td> </tr>
</tbody>
</table>
</div>
<div>
<span class='myTarget notSameAsTarget'>Stuff<span>
</div>
</body>
我的第一个想法是,这应该是一个递归函数,应该从根document.documentElement
开始
JS:
var root = document.documentElement;
var targetClass = 'myTarget';
var elementsWithTargetClass = []; // store in array
function traverse(element, targetClassName){
// get class of current element
var currentClass = element.className;
// add to array if class matches
if(currentClass.trim() === targetClassName)
elementsWithTargetClass.push(element);
// recursive call
if(element.children){
traverse(element, targetClassName);
}
}
有关我失踪的建议吗?
// recursive call - updated
if(element.children){
for(var child in element.children)
traverse(element.children[child], targetClassName);
}
答案 0 :(得分:8)
你对traverse()的递归调用传递了最初传入的相同元素,所以它只是一遍又一遍地做同样的事情,直到堆栈溢出(嘿!)。您需要为元素的每个子元素调用遍历,而不是将元素重新传入。
答案 1 :(得分:2)
使用document.querySelector
。这不是getElementsByClassName()
,也不是库。 ;)
document.querySelector('.myTarget')
答案 2 :(得分:2)
考虑具有多个类的元素,并以body
开头:
var targetClass = 'myTarget';
var elementsWithTargetClass = []; // store in array
var re = new RegExp("\\b" + targetClass + "\\b");
traverse(document.body);
for ( var j = 0; j < elementsWithTargetClass.length; ++j )
elementsWithTargetClass[j].style.fontWeight = "bold";
function traverse(element, targetClassName){
// get class of current element
var currentClass = element.className;
if (currentClass.match(re))
// add to array if class matches
// if(currentClass.trim() === targetClassName)
elementsWithTargetClass.push(element);
// recursive call
if(element.children){
for ( var i = 0; i < element.children.length; ++i )
traverse(element.children[i]);
}
}
&#13;
<div>
<ul>
<li class="myTarget">this</li>
<li class="myTarget andAnotherClass">also this</li>
<li>not this</li>
</ul>
</div>
&#13;
答案 3 :(得分:1)
您正在进行许多递归,这使得调用堆栈变得很高。尝试将递归函数转换为循环。这不应该给你任何问题。
答案 4 :(得分:1)
var root = document.documentElement;
var targetClass = 'myTarget';
var elementsWithTargetClass = []; // store in array
pre_order(root);
function pre_order(node) {
if(node.className == targetClass)
elementsWithTargetClass.push(node);
for(var i=0; i < node.childNodes.length; i++)
pre_order(node.childNodes[i]);
}
console.log(elementsWithTargetClass);