A polyfill that fires selectionchange
events for Firefox.
Firefox has a select
event for when the selection changes within
an input
or textarea
element, but doesn't yet support the general
selectionchange
event like other major browsers
(see feature request).
This polyfill models its behavior after Google Chrome’s.
Call selectionchange.start()
to enable the polyfill and selectionchange.stop()
to disable it. Both functions take an optional DOMDocument
argument, defaulting
to window.document
.
Handlers for the selectionchange
event should be registered on the document or
its .defaultView
(its window
).
The event is not cancellable and carries no information about the previous or current selection.
<script src="selectionchange.js"></script>
<script>
selectionchange.start();
document.addEventListener('selectionchange', function (event) {
var sel = this.getSelection();
console.log('Selected text:', sel.rangeCount ? sel.getRangeAt(0).toString() : null);
});
</script>
This polyfill fires selectionchange
immediately after most kinds of selection changes
(identified with checkmarks below), but there are some unsupported edge cases.
Ways a user can create a new selection:
- ✅ User presses primary mouse button
- ✅ User double-clicks a word or triple-clicks a paragraph
- ❌ User chooses "Select All" from the context (right-click) menu 1
- ❌ User chooses "Select All" from the Edit menu in the menu bar 1
- ✅ User types Ctrl+A (or Cmd+A) to select all
- ✅ User tabs to a different focusable element
Ways a user can modify a selection:
- ✅ User moves mouse while holding down primary mouse button
- ✅ User holds down Shift key (and optionally Alt key) and clicks and/or drags mouse
- ✅ User holds down Shift key (and optionally Alt key) and presses an arrow key
User scrolls the wheel with the primary mouse button down(a Chrome/Safari feature not in Firefox)
Ways a script can create or modify a selection:
- ❌ Using the Selection API 2
- ❌ Modifying the DOM within the selection, at a boundary, or with any overlap 2
- ✅ Moving focus using
.focus()
or.blur()
If the document’s selection changes via an unsupported mechanism, the selectionchange
event will not necessarily fire soon afterwards, but may still fire eventually, after
a subsequent user action.
1 The reason this polyfill doesn’t currently support "Select All" menu item selection is that it doesn’t trigger a DOM event and is less common. Optional support via polling may be added in the future.
2 The reason this polyfill doesn’t currently support selection changes via script
is that the author’s initial use case didn’t require it. Polling could be used
to detect changes via the Selection API. A DOM MutationObserver
could be
used to detect selection changes resulting from DOM modifications.