我最终发现最好的方法是手动操作。测试的关键是
node.assignedSlot
当元素被分配给槽时不为空,因此可以在扫描子元素时使用此选项,以便在将子元素分配给槽时忽略它们(并在扫描时包含它们
slot.assignedNodes()
这是一个带有
walk
用于遍历所提供元素的默认函数。
criteria
是每个节点的回调函数,调用者可以使用该函数检查节点是否满足查找的条件(请参见问题),因此不扫描子节点。
function _walk(node,criteria, slot) {
if (node.assignedSlot === null || node.assignedSlot === slot) {
if (node.localName === 'slot') {
const assignedNodes = node.assignedNodes();
if (assignedNodes.length === 0) {
_walkA(node.children, criteria);
} else {
_walkA(assignedNodes.filter(n => n.nodeType === Node.ELEMENT_NODE), criteria, node);
}
} else if (!criteria(node)) {
if (customElements.get(node.localName)) _walkA(node.shadowRoot.children,criteria);
_walkA(node.children, criteria);
}
}
}
function _walkA(nodes,criteria, slot) {
for (let n of nodes) {
_walk(n,criteria, slot);
}
}
export default function walk(walknode, criteria) {
_walk(walknode,criteria,null);
}