4

構文ベースのフォーマットを使用する Web ページ用の JavaScript エディターを作成しようとしています。innerHTMLを使用して<pre>タグの を完全に置き換えonkeyupます。ただし、これにより、キャレットがエディターの先頭に移動されます。

私が見つけることができる唯一の解決策は、変更が行われる前に選択の開始と終了のオフセットを取得し、それらを最後に設定することです。選択の開始と終了を取得するための私のコードは、https : //stackoverflow.com/a/4812022/2093695 から変更されています。

var selStart, selEnd;
if (typeof window.getSelection != "undefined") {
    var range = window.getSelection().getRangeAt(0);
    var preCaretRange = range.cloneRange();
    preCaretRange.selectNodeContents(editor);
    preCaretRange.setEnd(range.endContainer, range.endOffset);
    selStart = preCaretRange.toString().length;
    selEnd = selStart + range.toString().length;
} else if (typeof document.selection != "undefined" && document.selection.type != "Control") {
    var textRange = document.selection.createRange();
    var preCaretTextRange = document.body.createTextRange();
    preCaretTextRange.moveToElementText(editor);
    preCaretTextRange.setEndPoint("EndToEnd", textRange);
    selStart = preCaretTextRange.text.length;
    selEnd = selStart + textRange.text.length;
} else selStart = 0;

その部分は、少なくとも Firefox では問題なく動作します。私の問題は、選択の設定にあります。私がこれまでに持っているものは次のとおりです。

// restore selection
if (selStart) {
    if (range) {
        range = window.getSelection().getRangeAt(0);
        range.setStart(editor,selStart);
        range.setEnd(editor,selEnd);
        // Doesn't work, in FF at least
        // Behavior: when there are no tags,
        //     for 0, caret set at beginning
        //     for 1, caret set at end
        //     for anything greater, "IndexSizeError: Index or size is negative or greater than the allowed amount"
        // when the editor contains tags,
        //     for 0, caret set at beginning of editor
        //     for 1, caret set at beginning of first tag (unless same as start of editor)
        //     for 2, caret set at end of first tag
        //     for 3, caret set at beginning of second tag
        //     for 4, caret set at end of second tag, and so on
        //     for a number that is 1 greater than whatever number would set the caret at the end of the last tag, caret set at end of editor
        //     for a number greater than that, same error as before
    } else if (document.selection && document.selection.createRange) {
        // Not sure what to do here
    }
}

それはどのようsetStartに機能setEndするはずですか?私は何を間違っていますか?できればライブラリを使用せずに、選択の開始と終了を設定するより良い方法はありますか?

4

1 に答える 1

6

このためにいくつかの異なる関数を投稿しました。最新のものを見つけることができませんが、restoreSelection()役立つ関数を含む jsFiddle へのリンクが次のとおりです。

https://stackoverflow.com/a/7404126/96100

更新: このコードの最新バージョンを見つけました。同じように動作するはずですが、内部はもう少しエレガントです。

https://stackoverflow.com/a/13950376/96100

于 2013-04-05T08:52:38.383 に答える