查找具有没有库或 getElementsByClassName 的类的元素
Find an element with a class without library or getElementsByClassName
这是我被问到的问题,想知道该怎么做,或者这是否是一个技巧问题。我只用了一小段時間的JavaScript,所以我不太確定。
假设您有一个包含大量内容的网页。不使用任何库或getElementsByClassName,遍历DOM并找到具有特定类名的所有元素。
示例网页
<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);
}
您对 traverse() 的递归调用传递了最初传入的相同元素,因此它只是一遍又一遍地做完全相同的事情,直到堆栈溢出(嘿!您需要为元素的每个子级调用遍历,而不是将元素传递回去。
使用 document.querySelector
.这不是getElementsByClassName()
,也不是图书馆。;)
document.querySelector('.myTarget')
考虑具有多个类的元素,并以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]);
}
}
<div>
<ul>
<li class="myTarget">this</li>
<li class="myTarget andAnotherClass">also this</li>
<li>not this</li>
</ul>
</div>
您正在进入许多递归,这使得调用堆栈增长到高。尝试将递归函数追逐到循环中。这应该不会给您带来任何问题。
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);
JSFiddle
相关文章:
- CKEditor Widget-阻止编辑可编辑元素本身
- 如何设置html元素填充的动画
- 如何将HTML id分配给元素,以及如何将JavaScript应用于元素
- 使用 jQuery 的 .on 函数如何获取事件的原始元素
- 使用clickToggle并在单击另一个元素时关闭元素
- 单击时将焦点更改为元素
- 表追加而不附加最后一个元素
- 如何在jQuery中获取元素的形式
- 我可以获得相对于被点击元素的确切点击位置吗
- 在函数中添加数组元素的数值
- 在单击任何位置时隐藏元素,而不检查每次DOM单击
- 将视口底部滚动到元素底部
- 是否有任何snippet或jQuery插件可以列出easylist.txt模式匹配的DOM中的所有元素
- 在不使用JQuery的情况下隐藏DOM中的选定元素
- 如何使用jquery处理php循环通过元素
- Ckeditor-plugin:插入虚假元素add不情愿<p>标签前后
- JQuery添加元素需要在我的js之前再次添加JQuery脚本
- 在Jquery detachment()和appendTo()之后定位元素
- 在动态创建的元素上获取对特定选择器的引用
- 根据元素和容器大小计算边距