我试图遍历文档中的所有元素,并提取具有目标类名的元素。重要的是,我需要在不使用document.getElementsByClassName(className) / document.querySelectorAll等工具的情况下这样做--这就是这个学习练习的要点。
以下是javascript:
var getElementsByClassName = function(className){
var rootElem = document.body;
var collectionResult = [];
if (rootElem.getAttribute("class") == className) {
collectionResult.push(rootElem);
};
var nextTier = function(collectionResult, rootElem) {
var thisTier = rootElem.children;
for (i=0; i<thisTier.length; i++) {
var classes = thisTier[i].getAttribute("class");
if (classes != undefined && classes.includes(className)) {
collectionResult.push(thisTier[i]);
};
var childrenArray = thisTier[i].children;
if (childrenArray.length > 0) {
nextTier(collectionresult, childrenArray)
};
};
};
nextTier(collectionResult, rootElem);
return collectionResult;
};下面是我遇到问题的HTML结构的部分:
<p>
<div class="somediv">
<div class="innerdiv">
<span class="targetClassName">yay</span>
</div>
</div>
</p>该代码适用于页面的其余部分,可以使用任意数量的非嵌套元素。但是,一旦var childrenArray = thisTier[i].children到达div.somediv元素,它就有childrenArray == undefined,而不是拉出div.innerdiv元素。
我是否误解了element.children的工作方式?
发布于 2015-05-29 17:46:29
你好像把事情搞得太复杂了。
function getElementsByClassName(className, root) {
if(!root) root = document.documentElement;
return [].reduce.call(root.children, function(arr, child) {
if(child.classList.contains(className)) arr.push(child);
return arr.concat(getElementsByClassName(className, child))
}, []);
}
function getElementsByClassName(className, root) {
if(!root) root = document.documentElement;
return [].reduce.call(root.children, function(arr, child) {
if(child.classList.contains(className)) arr.push(child);
return arr.concat(getElementsByClassName(className, child))
}, []);
}
console.log(getElementsByClassName("targetClassName"));<div class="somediv targetClassName">
<div class="innerdiv">
<span class="targetClassName">yay1</span>
</div>
</div>
<div class="somediv targetClassName">
<div class="innerdiv targetClassName">
<span class="targetClassName">yay2</span>
</div>
</div>
<div class="somediv">
<div class="innerdiv">
<span class="targetClassName">yay3</span>
</div>
</div>
发布于 2015-05-29 16:40:10
Array.prototype.flatMap是一种有效的工具,可以将树(如DOM)扁平为一个值数组(如元素列表)-
function getElementsByClassName (node, query) {
function matchAll (children) {
return Array
.from(children)
.flatMap(c => getElementsByClassName(c, query))
}
if (node.classList && node.classList.contains(query))
return [ node, ...matchAll(node.childNodes) ]
else
return matchAll(node.childNodes)
}
const result =
getElementsByClassName(document, "targetClassName")
console.log(result)
// [ <div class="somediv targetClassName">…</div>
// , <span class="targetClassName">yay1</span>
// , <span class="targetClassName">yay2</span>
// , <span class="targetClassName">yay3</span>
// ]<div class="somediv targetClassName">
<div class="innerdiv">
<span class="targetClassName">yay1</span>
</div>
</div>
<div class="somediv">
<div class="innerdiv">
<span class="targetClassName">yay2</span>
</div>
</div>
<div class="somediv">
<div class="innerdiv">
<span class="targetClassName">yay3</span>
</div>
</div>
https://stackoverflow.com/questions/30534016
复制相似问题