设置选择开始和结束在一个contentedible

Bri*_*hon 4 javascript range selection contenteditable

我正在尝试为使用基于语法的格式的网页创建JavaScript编辑器.它完全取代innerHTML<pre>标签的使用onkeyup.但是,这会导致插入符号移动到编辑器的开头.

我能找到的唯一解决方案是在更改之前获取选择开始和结束的偏移量,然后在结束时设置它们.我从/sf/answers/336841571/修改了获取选择开始和结束的代码:

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;
Run Code Online (Sandbox Code Playgroud)

至少在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
    }
}
Run Code Online (Sandbox Code Playgroud)

是如何setStartsetEnd都应该工作?我究竟做错了什么?是否有更好的方法来设置选择的开始和结束,最好不使用库?

Tim*_*own 6

我已经为此发布了几个不同的功能.我找不到我最近的那个,但是下面有一个链接到jsFiddle包含一个restoreSelection()应该有用的函数:

/sf/answers/518288851/

更新:我找到了此代码的更新版本.它应该工作相同,但内部更优雅.

/sf/answers/976526351/