In JavaScript range selection is it possible to prevent selection of a partial node?
For example:
"The enormous cat sat on the very small rug."
A user might select "cat" and more often than not, their mouse selection is not that precise and includes the visible space either side as well, and thus the selection range nearly always includes "enormous" and "sat" which we do not want.
Each span contains a single word. The visible space in between words could be true whitespace inside a span tag, spans stacked with line-breaks, it could be padding, it also could be css word-space, or even a non-breaking space. Whichever way if the user’s selection strays into another node unintentionally, the default is of course is to return the node as part of the selection.
How can this be avoided?
Any pointers gladly accepted.
Thank you kindly.
Example code:
<span id="a1">The </span>
<span id="a2">enormous</span>
<span id="a3"> cat </span><span id="a4">sat</span>
<span id="a5"> on </span><span id="a6" style="padding-right: 2px;">the</span>
<span id="a7">very </span><span id="a8">small </span><span id="a9">rug</span><span id="a10">. </span>
2
Answers
Here is a script you can build on using Selection API
I think i have finally nailed it. Lets take start and end span from selection range and check if trimmed span content equals to trimmed span selection (that part that is actually selected in span). If there is only white space selected or partially selected text in span exclude it from selection. Check for
parentNode !== SPAN
is for case when only white space is selected.UPDATE 19.1.2023:
Another solution can be using selection manipulation as we can expand/shrink selection to the word boundary. See How do I extend selection to word boundary using JavaScript, once only?
The idea is to shrink selection to the word boundary, get selected text, trim and split by regex (one or more whitespace characters):
Note: strange thing is that selection manipulation works fine on my test page, but not in SO code snippet.