JavaScript: Tracking Selection Change on Firefox for Android
Asked Answered
M

1

9

I'm looking for a way to track the text selection on a web page. I need some code to be executed whenever there is a change in selection. I have successfully done this on all major desktop browsers, but the same does not seem to be working on Firefox for Android.

I tried three approaches (none of them worked!):

  1. Tried catching the "mouseup" event and checking if there is a non-empty text selection. Problem is "mouseup" isn't getting triggered if a selection was made during the mousedown-move-up sequence!
  2. Tried doing the same with the "touchend" event - Same result.
  3. Tried catching the "selectionchange" event. I saw that it isn’t triggered when the selection changes as it needs the config key "dom.select_events.enabled" to be set. This is false by default and I obviously can't ask my visitors to tweak browser settings :-)

Also, as expected, the first two events don't get triggered if the selection is extended or reduced by dragging the selection start/end markers.

The only solution I can think of now is a periodic poller (using setInterval) that checks if there is a text selection. This is definitely unclean and anti-performance.

Any alternatives and/or advice will be very helpful.

Melbamelborn answered 20/8, 2016 at 4:28 Comment(4)
where are you binding mouseup event, to body/document/html? try combination of them.Peneus
Just tested it on firefox mobile and indeed it doesn't trigger any event >.>Dayledaylight
You can create a poller when a selection has started using the mouseup event and then remove the poller when there hasn't been a selection for X seconds. Can't think of anything else to solve this besides hoping that the selectionchange event becomes default soon :/Dayledaylight
Yes, that's kind of what I'm doing now. I'm starting the poller on mousedown in fact, and clearing it when there isn't a selection change for 3 seconds. Feels very unclean but. The poller runs every 500ms which luckily doesn't seem to be affecting the performance as of now.Melbamelborn
M
2

1) Native Text Selection Events

Currently, polling seems to be the only work-around. However, the selectionchange event is currently experimentally implemented in Firefox for Android Nightly. It can be enabled by setting the dom.select_events.enabled flag to true (defaults to false).

In Nightly builds, this flag already defaults to true, so there is a chance you can use it normally in a couple of months.

 

2) Find events that work

(UNTESTED!!)

Even if onselectstart cannot be used productively in Firefox for Android yet, the only viable easy solution is polling.

To improve performance and reduce costs, polling can be started on the window blur event. Because whenever the user is making a selection, the focus should be set off the viewport (untested though).

window.addEventListener('blur', function(){
    // start polling for text selections
});

When the focus is given back, polling can be stopped.

window.addEventListener('focus', function(){
    // stop polling
});

To check if the browser actually supports text selection events, you can use this function:

var browserSupportsTextSelectionEvents = function(){
    return !!('onselectstart' in document.body);
}

 

3) Hacking

A third idea is to disable text selection for mobile Firefox users via CSS (-moz-user-select: none), implement a custom text selection function based on touch start and end positions and pushing the native selection range back to the browser via HTMLElement.setSelectionRange().

Muckraker answered 29/8, 2016 at 9:25 Comment(2)
Yeah, polling seems to be the only way out for now, at least till selectionchange is adopted into the stable channel. Thanks anyway for your efficiency related inputs regarding when to start/stop the poller. Though I'm yet to test it, it does look like the way forward. Thanks.Melbamelborn
I think the "Hacking" method (3) is the most promising. I can't try it because I have no Android + Firefox to test it, but with this solution no polling is needed. Just hook window.getSelection() after the touchend event. This event will be fired if user selection is disabled via CSS.Muckraker

© 2022 - 2024 — McMap. All rights reserved.