Introduction
Two years ago, a document product included a text selection-based comment feature that had been running smoothly.
Suddenly, just recently, a user casually brought up, “Why can’t I use the text selection comment feature on my phone?”
And just like that, a new feature request was born.
Back then, we faced conflicts between the built-in copy, translate, and other tips on mobile devices and the small button for text selection comments. Combined with development challenges (like simulating a long touch press on desktop), we chose not to implement it at the time.
After some quick research, it turns out the event is universal — it’s the selectionchange
event.
Understanding the selectionchange Event
According to my tests, the selectionchange
event is triggered whenever the selection range changes. For example, if you drag the “selection handles” to adjust the selected text, this event is continuously triggered.
Usage Example:
<div class="container">
Harry Potter is a novel series written by the British author J. K. Rowling. The book tells the adventure story of
young wizard Harry Potter with his friends at witchcraft and wizardry school.
</div>
<div>
selected content is:
<span id="result" style="color: green;"></span>
</div>
document.addEventListener('selectionchange', function () {
const selection = document.getSelection();
const result = document.getElementById('result');
result.textContent = selection.toString().trim();
});
At this point, whenever we select any text, the span#result element will display the selected text. Here’s a screenshot for reference:
Differences in Timing of Selection Events
On PC and mobile devices, the timing of when the text selection disappears is different, so the interaction handling varies accordingly.
For example, when we select some text and hover over a button, then click it, we use the surroundContents()
API to wrap the selected text. On the PC, we can use the click event for the button.
This is because, on the PC (and apparently on Android as well), the text selection disappears after the click event.
However, on iOS, it seems that the selection disappears before the click event, possibly due to issues with the client app.
Therefore, in actual implementation, the button’s click event needs to be handled using the touchstart event instead.
This is one of the execution details, and I hope it can be helpful to others working on similar requirements.
Attaching Elements and Event Objects for selectionchange
The selectionchange event can only be bound to the document and native input elements. It cannot be bound to regular elements.
For example, the following JS code will not trigger any behavior:
document.body.addEventListener('selectionchange', function () {
// nothing happen
});
However, if it’s an input field, such as <input>
or <textarea>
, there is no issue. For example:
input.addEventListener('selectionchange', function () {
});
What if it’s a regular element, but with contenteditable=“true” set, making it editable? Does it still support selectionchange
?
Based on my tests, it does not support it.
Event Object
Compared to traditional events, the event object for the selectionchange
event is missing a lot of information, such as coordinates. Taking Chrome as an example, the supported properties are shown in the screenshot below.
Therefore, if you want to position an element relative to the selection, the event object won’t be helpful. You will still need to use the selection’s own API.
Finally
It’s a relatively obscure JS DOM event API, but from my experience, it’s quite useful and stable, with good compatibility, as shown in the screenshot below: