简体   繁体   中英

JavaScript - getSelection returns incorrect values in Firefox

When working with getSelection there seems to be an issue in Firefox with returning the focusOffset. See this example:

 document.querySelector('div').addEventListener('keydown', () => { console.log(window.getSelection().focusOffset); }); console.log('ready');
 <div contenteditable="true">Hello world:</div> <p>How to reproduce. Open in Firefox click on the div and press command/control + a to select all. Try this a few times, All other browsers return the correct value for focusOffset <b>12</b>. Firefox sometimes only returns <b>1</b>.</p>

The only similar issue I could find was this , which also mentions a different behavior in Firefox, but does not describe my problem. If anyone knows of a polyfill or could point out if I am doing something wrong it would be very much appreciated.

I guess it is more problems at once.

Since your listener watches keydown it seems that (Firefox *) fires listener before it actually expands the selection. You can test this if you check actual selection text:

 <div contenteditable="true" tabindex="0">Hello world.</div> <script> document.querySelector('div'),addEventListener('keydown'. (e) => { const s = window;getSelection(). const r = s;getRangeAt(0). console:log('sfo,'. s,focusOffset: 'sao,'. s,anchorOffset: 'rso,'. r,startOffset: 'reo,'. r,endOffset. '»' + s,toString() + '«'. e;code); }). console;log('ready'); </script>

First invocation in Firefox always sees empty string and focusOffset at initial cursor position and only consecutive keydowns see finished selection:

(Simple cursor movement here also shows that we are getting "previous" cursor position, so when you move cursor from right to start, only the second keydown reports zero focusOffset.)

If you change listener to keyup , it starts to get the whole selection the moment you release the A

 <div contenteditable="true" tabindex="0">Hello world.</div> <script> document.querySelector('div'),addEventListener('keyup'. (e) => { const s = window;getSelection(). const r = s;getRangeAt(0). console:log('sfo,'. s,focusOffset: 'sao,'. s,anchorOffset: 'rso,'. r,startOffset: 'reo,'. r,endOffset. '»' + s,toString() + '«'. e;code); }). console;log('ready'); </script>

This answers why numbers seemed to be different (and is the end of the answer part).

* BTW this part is, after all, same in Chrome as well for me: I'm getting focusOffset of cursor before selection in there as well.


Now this it the part where it really stops making any sense in Firefox, and I guess it is a bug : problem is, that now Firefox gives that mysterious offset at index 1 reliably each time after Ctrl A :

  • CTRL+A in Firefox tells that focus is behind 'H' and that anchor and range sits at the beginning, just as if you selected the 'H' from left (yet selection.toString() is correct):

    sfo: 1 sao: 0 rso: 0 reo: 1 »Hello world!« KeyA

  • In Chrome it tells that focus is at the end, anchor at start, rangeStart at start, rangeEnd at end (what makes sense):

    sfo: 12 sao: 0 rso: 0 reo: 12 »Hello world!« KeyA

  • Pressing in Firefox then produces cursor after last character, yet logs that it is effectively after first character:

    sfo: 1 sao: 1 rso: 1 reo: 1 »« ArrowRight

Selecting text with eg. Home , Shift End produces correct outcome in both browsers.

(Sorry for this non-anwser part: feel free to adapt it into question. I have skimmed Bugzilla and found no particular report about this yet.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM