我写了一个解决方法(在打字稿中)
function getRangePartiallySelectedNodes(
selection: Selection,
parent: Node
): Node[] {
return [
// containsNode doesn't work as expected, always gives partial nodes
...(selection.containsNode(parent, true) ? [parent] : []),
...(parent.hasChildNodes()
? Array.from(parent.childNodes)
.map((node) => getRangePartiallySelectedNodes(selection, node))
.flat()
: []),
];
}
function isAncestor(node: Node, possibleAncestor: Node): boolean {
if (!node || !node.parentNode) return false;
return (
node.parentNode.isSameNode(possibleAncestor) ||
isAncestor(node.parentNode, possibleAncestor)
);
}
export function selectionContainsNodes(
sel: Selection,
// limitation: the selection must be within the elementEditing node
elementEditing: HTMLElement
): boolean {
if (sel.isCollapsed) return false;
const nodes = getRangePartiallySelectedNodes(sel, elementEditing);
// sel.anchorNode and sel.focusNode may be parents of the actual selection start instead of the selection themselves
return nodes.some(
(node) =>
!isAncestor(sel.anchorNode, node) &&
!node.isSameNode(sel.anchorNode) &&
!isAncestor(sel.focusNode, node) &&
!node.isSameNode(sel.focusNode)
);