Javascript Contenteditable - 将 Cursor/Caret 设置为索引

标签 javascript jquery contenteditable

我将如何修改此 ( How to set caret(cursor) position in contenteditable element (div)?) 以便它接受数字索引和元素并将光标位置设置为该索引?

例如: 如果我有段落:

<p contenteditable="true">This is a paragraph.</p>

我调用:

setCaret($(this).get(0), 3)

光标会像这样移动到索引 3:

Thi|s is a paragraph.

我有这个但没有运气:

function setCaret(contentEditableElement, index)
{
    var range,selection;
    if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
    {
        range = document.createRange();//Create a range (a range is a like the selection but invisible)
        range.setStart(contentEditableElement,index);
        range.collapse(true);
        selection = window.getSelection();//get the selection object (allows you to change selection)
        selection.removeAllRanges();//remove any selections already made
        selection.addRange(range);//make the range you have just created the visible selection
    }
    else if(document.selection)//IE 8 and lower
    { 
        range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
        range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
        range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
        range.select();//Select the range (make it the visible selection
    }
}

http://jsfiddle.net/BanQU/4/

最佳答案

这是改编自 Persisting the changes of range objects after selection in HTML 的答案.请记住,这在几个方面并不完美(就像 MaxArt 一样,它使用相同的方法):首先,只考虑文本节点,这意味着 <br> 隐含的换行符。并且 block 元素不包含在索引中;其次,所有文本节点都被考虑在内,即使是那些被 CSS 隐藏的内部元素或 <script> 内部的元素。要素;第三,将页面上折叠的连续空白字符全部纳入索引;最后,IE <= 8 的规则再次不同,因为它使用了不同的机制。

var setSelectionByCharacterOffsets = null;

if (window.getSelection && document.createRange) {
    setSelectionByCharacterOffsets = function(containerEl, start, end) {
        var charIndex = 0, range = document.createRange();
        range.setStart(containerEl, 0);
        range.collapse(true);
        var nodeStack = [containerEl], node, foundStart = false, stop = false;

        while (!stop && (node = nodeStack.pop())) {
            if (node.nodeType == 3) {
                var nextCharIndex = charIndex + node.length;
                if (!foundStart && start >= charIndex && start <= nextCharIndex) {
                    range.setStart(node, start - charIndex);
                    foundStart = true;
                }
                if (foundStart && end >= charIndex && end <= nextCharIndex) {
                    range.setEnd(node, end - charIndex);
                    stop = true;
                }
                charIndex = nextCharIndex;
            } else {
                var i = node.childNodes.length;
                while (i--) {
                    nodeStack.push(node.childNodes[i]);
                }
            }
        }

        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    }
} else if (document.selection) {
    setSelectionByCharacterOffsets = function(containerEl, start, end) {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(containerEl);
        textRange.collapse(true);
        textRange.moveEnd("character", end);
        textRange.moveStart("character", start);
        textRange.select();
    };
}

关于Javascript Contenteditable - 将 Cursor/Caret 设置为索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16095155/

相关文章:

javascript - 从 JavaScript 中的 AJAX 调用返回 POST 结果

javascript - 使用受控输入 react contentEditable div

firefox - 无法通过单击 FF 中的 div contenteditable 来更改光标位置

javascript - JQGrid 在发布到服务器之前序列化数据

javascript - 具有不同 ID 的 HTML 表正在从 AJAX 回调接收相同的值

javascript - IE10 和图像/ Canvas 的跨域资源共享 (CORS) 问题

html - 如何使用 `execCommand("insertoredlist")`?

javascript - react : store state to template literals

javascript - vuejs MaterializeCSS timepicker 没有获取值

jquery - Blueimp 获取上传的文件名