構文ベースのフォーマットを使用する 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
するはずですか?私は何を間違っていますか?できればライブラリを使用せずに、選択の開始と終了を設定するより良い方法はありますか?