3

contenteditable DIV 内で、ユーザーが左から右または右から左から選択したかどうかを判断したいと思います。ブラウザー Firefox、Chrome、Safari、Opera 用の Javascript ソリューションを持っている人はいますか? 可能であれば、IE 用のものも?

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

ここで jsFiddle のコードを準備しました: http://jsfiddle.net/ecUka/

前もって感謝します :-)

4

2 に答える 2

11

以下は、DOM Range の終了を範囲の開始よりもドキュメント内の前のポイントに設定すると、範囲が折りたたまれるという事実を利用する関数です。

デモ: http://jsfiddle.net/97MDR/17/

コード:

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;
}

他のブラウザーと同じ範囲および選択 API をサポートしていない IE < 9 を除いて、すべての主要なブラウザーで動作します。

IE < 9 の場合、選択 API には、選択方向について通知するものは何もありません。私が提案できる最善の方法は、selectionchangeイベントを使用して、以前に選択した範囲を追跡し、発生するたびにどちらの端が変化したかを確認することです。次の例では機能しているように見えますが、それ以外のテストは行っていないため、自己責任で使用してください。

デモ: http://jsfiddle.net/97MDR/18/

追加コード:

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;
        }
    }
};
于 2012-09-29T10:56:08.460 に答える