gpt4 book ai didi

javascript - 使用 RAMDA 减少 DOM 树

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:13:20 28 4
gpt4 key购买 nike

我想遍历浏览器中的 DOM 树,收集作为“叶子”的 DOM 节点,不包含 DOM 子节点,只包含文本节点。

我想有一种方法可以用 reduce 来做到这一点,但我不太清楚如何......在树状结构上递归减少。

我构建了一堆可用的组件...

let nodeFromJQuery = R.invoker(1,'get')(0);
let nodeFromAny = R.ifElse(R.isArrayLike,nodeFromJQuery,R.identity);
let nodeType = R.pipe(nodeFromAny,R.prop('nodeType'));
let children = R.pipe(nodeFromAny,R.prop('childNodes'));
let textNodeType = R.equals(3);
let domNodeType = R.equals(1);

let domNodes = R.map(isDomNode);
let textNodes = R.map(isTextNode);

let isTextNode = R.pipe(nodeType, textNodeType);
let isDomNode = R.pipe(nodeType,domNodeType);
let domChildren = R.pipe(children,R.filter(isDomNode));

isLeaf = R.pipe(domChildren, R.isEmpty);

getNodes = R.filter(R.not(isLeaf));
getLeaves = R.filter(isLeaf)

但我没有看到简单的减少......有什么想法吗?

谢谢,

最佳答案

您可以采用的一种方法是为 Node 实例创建一个包装器类型,其中包含一个 Ramda 可以分派(dispatch)的 reduce 方法,允许您总结整个节点树节点实例。

const node = (n) => ({
reduce(f, z) {
switch(n.nodeType) {
case Node.TEXT_NODE:
return f(z, n)
case Node.ELEMENT_NODE:
return R.reduce(
(_z, _n) => node(_n).reduce(f, _z),
f(z, n),
n.childNodes
)
default:
return z // ignore other node types
}
}
})

如果您有兴趣收集 Text 节点的列表,您现在可以通过 reduce 有选择地将它们添加到列表中。

const isInterestingTextNode = R.both(
R.propEq('nodeType', Node.TEXT_NODE),
R.propSatisfies(R.complement(R.test(/^\s*$/)), 'textContent')
)

const textNodesOf = R.pipe(node, R.reduce((textNodes, node) => {
if (isInterestingTextNode(node)) textNodes.push(node.textContent)
return textNodes
}, []))

您可以在下面的代码片段中看到这方面的示例。

const node = (n) => ({
reduce(f, z) {
switch(n.nodeType) {
case Node.TEXT_NODE:
return f(z, n)
case Node.ELEMENT_NODE:
return R.reduce(
(_z, _n) => node(_n).reduce(f, _z),
f(z, n),
n.childNodes
)
default:
return z // ignore other node types
}
}
})

const isInterestingTextNode = R.both(
R.propEq('nodeType', Node.TEXT_NODE),
R.propSatisfies(R.complement(R.test(/^\s*$/)), 'textContent')
)

const textNodesOf = R.pipe(node, R.reduce((textNodes, node) => {
if (isInterestingTextNode(node)) textNodes.push(node.textContent)
return textNodes
}, []))

console.log(textNodesOf(document.getElementById('root')))
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.22.1/ramda.min.js"></script>
</head>
<body>
<div id="root">
<div>
<span>foo</span>
</div>
<div>
<span>bar</span>
</div>
</div>
</body>
</html>

关于javascript - 使用 RAMDA 减少 DOM 树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39778315/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com