Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if a selection in a contenteditable DIV is from left-to-right or from right-to-left

Within a contenteditable DIV, I want to determine, if the user made a selection from left-to-right or from right-to-left. Does someone have a Javascript solution for the Browsers Firefox, Chrome, Safari, Opera? And when possible, also one for IE?

<div id="editor" contenteditable>
Selection from Cursor end | here <strong>over bold</strong> to Cursor start | here.
</div>

I prepared the code in jsFiddle here: http://jsfiddle.net/ecUka/

Thank's in advance :-)

like image 301
Max Avatar asked Oct 22 '25 07:10

Max


1 Answers

Here's a function that uses the fact that setting the end of a DOM Range to be at an earlier point in the document than the start of the range will collapse the range.

Demo: http://jsfiddle.net/97MDR/17/

Code:

function isSelectionBackwards() {
    var backwards = false;
    if (window.getSelection) {
        var sel = window.getSelection();
        if (!sel.isCollapsed) {
            var range = document.createRange();
            range.setStart(sel.anchorNode, sel.anchorOffset);
            range.setEnd(sel.focusNode, sel.focusOffset);
            backwards = range.collapsed;
        }
    }
    return backwards;
}

Demo:

function isSelectionBackwards() {
    var backwards = false;
    if (window.getSelection) {
        var sel = window.getSelection();
        if (!sel.isCollapsed) {
            var range = document.createRange();
            range.setStart(sel.anchorNode, sel.anchorOffset);
            range.setEnd(sel.focusNode, sel.focusOffset);
            backwards = range.collapsed;
        }
    }
    return backwards;
}

document.addEventListener("selectionchange", function() {
  document.getElementById("selReport").textContent = isSelectionBackwards();
});
<p>Select something forwards and backwards in here</p>
<p>Selection is backwards: <strong id="selReport">false</strong><p>

Unless you need to support Internet Explorer <9, which seems highly unlikely in 2023, you can safely ignore the rest of this answer, which I'm leaving here for posterity.


The above works in all major browsers except IE < 9, which does not support the same Range and Selection APIs as other browsers.

For IE < 9, there is simply nothing in the selection API to tell you about the selection direction. The best I can suggest is using the selectionchange event to keep track of the previously selected range and see which end has changed each time it fires. It seems to work in the following example but has had no testing apart from that, so use at your own risk.

Demo: http://jsfiddle.net/97MDR/18/

Additional code specific to IE < 9 that won't work in modern browsers:

var selectedRange, selectionBackwards;

document.onselectionchange = function(evt) {
    evt = evt || window.event;
    var sel = document.selection;
    if (sel && sel.type !== "Control") {
        if (sel.type == "Text") {
            // Selection is not collapsed, so compare range end points
            var newRange = sel.createRange();
            if (selectedRange) {
                var startChanged = (newRange.compareEndPoints("StartToStart", selectedRange) != 0);
                var endChanged = (newRange.compareEndPoints("EndToEnd", selectedRange) != 0);

                if (startChanged && !endChanged) {
                    selectionBackwards = true;
                } else if (endChanged && !startChanged) {
                    selectionBackwards = false;
                } else if (startChanged && endChanged) {
                    // Both ends have changed, which is confusing.
                    // I suspect this can happen when the selection snaps
                    // to words. In this case we can tell nothing, so leave
                    // selectionBackwards alone.
                } else {
                    // Neither end has changed, so we can tell nothing.
                }
            }
            
            selectedRange = newRange;
        } else {
            // Selection is collapsed
            selectionBackwards = false;
        }
    }
};
like image 151
Tim Down Avatar answered Oct 23 '25 20:10

Tim Down



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!