In selection, can the focusOffset be before the an

2019-07-04 05:47发布

问题:

In programmatically defining a range/selection in JavaScript, is it not possible to have the focusOffset in the range be before the anchorOffset? How do we define a right to left selection then?

a JS fiddler link for example: http://jsfiddle.net/johncch/ejVab/1/

回答1:

The way to create a "backwards" selection is slightly non-obvious. It can't be done by simply selecting a Range via the selection addRange() method because ranges are intrinsically directionless. You need to use the extend() method of the selection (example below).

Note this doesn't work in any version of IE, including 9: unlike previous versions, IE 9 does have standard selection and range objects but at the time Microsoft was developing IE 9, extend() was non-standard so they didn't implement it, meaning that there is no way to create a backwards selection programmatically in any version of IE yet released. IE 10 did not implement extend(), despite my filing a bug on the IE bug tracker.

function selectRangeBackwards(range) {
    var sel = window.getSelection();
    var endRange = range.cloneRange();
    endRange.collapse(false);
    sel.removeAllRanges();
    sel.addRange(endRange);
    sel.extend(range.startContainer, range.startOffset);
}


回答2:

You need to swap two variables then:

function makeSelection(a, b) {
    if(b < a) {
        var tmpA = a;
        a = b;
        b = tmpA;
    }
    // ... rest of your code

updated jsfiddle demo.



回答3:

This is a good MDN doc on the selection. The anchorOffset/anchorNode denotes the "start" of the selection (where it was started, say, during a mouse drag), while focusOffset/focusNode denotes the "end" of the selection (where the user finished the drag). This is of little use for determining the left/right ends of a selection. To detect them, you need the Range object - use startContainer/startOffset for the left selection boundary, and endContainer/endOffset for the right boundary. Get the range from your selection as

if (window.getSelection() && window.getSelection().rangeCount)
    var range = window.getSelection().getRangeAt(0);

Guess this is enough to build the right selection.