Let's say I have a random string (span
) of characters, each in their own span
. A user can select these. I want to know which ones they select. The window.GetSelection
API is useful here. It returns a Selection. However, I can't seem to figure out how I can get which characters the user selected, i.e. a NodeList
of character spans. I do not mean simply which string it is (which you can get with .toString()
) but also which character spans the selection belongs to.
I know there is Selection.anchorNode
and Selection.focusNode
as the respective start and end nodes but I want to get all of the selected nodes.
In the snippet below you can have a look.
function getSelectionNodes() {
const selection = window.getSelection();
let anchor = selection.anchorNode,
focus = selection.focusNode;
anchor = anchor.nodeType === Node.TEXT_NODE ? anchor.parentNode : anchor
focus = focus.nodeType === Node.TEXT_NODE ? focus.parentNode : focus
const anchorIdx = getIndex(anchor),
focusIdx = getIndex(focus);
console.log(anchor);
console.log(focus);
};
function getIndex(el) {
return Array.from(el.parentNode.children).indexOf(el)
}
<span onmouseup="getSelectionNodes()">
<span>d</span>
<span>d</span>
<span>s</span>
<span>r</span>
<span>e</span>
<span>g</span>
<span>p</span>
<span>j</span>
<span>l</span>
<span>u</span>
</span>
Note a particular difficulty: If you select a couple of letters and a seeming "space" after them, you'll notice that the anchor will not be a character span, but the parent span because we selected the "space between" the character spans, which is a text node with the wrapper span. This seems problematic. If I could get the starting and ending character span, I could use an while loop with nextSibling
or previousSibling
to get what I want, I think.