我試圖爲使用基於語法的格式的網頁創建一個JavaScript編輯器。它使用onkeyup
完全取代<pre>
標籤的innerHTML
。但是,這會導致插入符號被移到編輯的開頭。
我能找到的唯一解決方案是在更改前獲取選擇開始和結束的偏移量,然後在最後設置它們。我對獲得選擇開始和結束碼從https://stackoverflow.com/a/4812022/2093695修改:設置選擇開始和結束在一個contentedible
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
都應該工作?我究竟做錯了什麼?有沒有更好的方法來設置選擇的開始和結束,最好是不使用庫?
記住直接編輯'innerHTML'導致要刪除的撤銷/重做緩衝區。進入類似的問題發展[tabIndent.js](http://julianlam.github.com/tabIndent.js)。 – 2013-04-05 02:58:36
@ Julian:謝謝你的提醒。我意識到這一點,並考慮使用某種替代方法,例如將編輯器的全部內容作爲範圍並使用'var code = range.toString();'後跟'range.deleteContents(); ','code = range.createContextualFragment(code);','range.insertNode(code);' – 2013-04-05 03:08:16