3 回答

TA贡献1809条经验 获得超8个赞
所以你试图通过递归函数遍历 DOM 树!?
当然,每个孩子都有自己的一组孩子。不然就不是树了。
当您想要返回所有匹配元素的数组时,您必须将结果与递归调用连接起来。
这可以工作:
const getElementsByClassName = (nameOfClass, parent) => {
const result = []
if (parent.className === nameOfClass) {
result.push(parent);
}
for(let el of parent.children) {
result = result.concat(getElementByClassName(nameOfClass, el));
}
return result
};
此实现应仅用于教育目的,因为它具有很大的存储复杂性。

TA贡献1829条经验 获得超6个赞
您可以像这样使用 querySelectorAll :
const getElementsByClassName = (nameOfClass, ancestor) => (
ancestor.querySelectorAll(`.${nameOfClass}`)
);
或者,如果您肯定想要父母的直系后代。es6方式:
const getElementsByClassName = (nameOfClass, parent) => (
[...parent.querySelectorAll(`.${nameOfClass}`)].filter(item => item.parentElement === parent))
);
javascript方式
const getElementsByClassName = (nameOfClass, parent) => (
Array.prototype.slice.call(parent.querySelectorAll(`.${nameOfClass}`)).filter(item => item.parentElement === parent))
);
很遗憾,我们不能将直接后代与 querySelectorAll 一起使用。否则这将是完美的:
const getElementsByClassName = (nameOfClass, parent) => (
parent.querySelectorAll(`> .${nameOfClass}`)
);

TA贡献1873条经验 获得超9个赞
这样的事情应该这样做:
const getElementsByClassName = (name, el) =>
[
... (el .classList .contains (name) ? [el] : []),
... ([... el .childNodes] .flatMap (c => getElementsByClassName (name, c)))
]
从逻辑上讲,这只是说将测试该节点(使用它的classList)的结果与flatMap对其子节点的ped 递归调用相结合。
现场示例:
const getElementsByClassName = (name, el) =>
[
... ([...(el .classList || [])] .includes (name) ? [el] : []),
... ([... el .childNodes] .flatMap (c => getElementsByClassName (name, c)))
]
console .log (
getElementsByClassName ('foo', document).map(el => el.textContent)
)
.foo {background: yellow; font-weight: bold}
<div class = 'foo'>Foo</div>
<div class = 'bar'>Bar</div>
<div class = 'baz'>
Baz
<div class = 'baz qux'>
Qux
<div class = 'foo baz qux'>Foo Baz Qux</div>
</div>
<div class = 'baz foo'>Baz Foo</div>
</div>
这在 DOM 遍历中可能过于简单,因为并非所有子节点都是元素,但这可能只是第二次检查。这应该表明这个想法。
添加回答
举报