在内容可编辑div中的光标处插入文本

use*_*362 48 javascript contenteditable

我有一个令人满意的div,我需要在插入位置插入文本,

这可以在IE中轻松完成 document.selection.createRange().text = "banana"

有没有类似的方法在Firefox/Chrome中实现这一点?

(我知道这里存在一个解决方案,但它不能在contenteditable div中使用,看起来很笨拙)

谢谢!

Tim*_*own 127

以下函数将在插入符号位置插入文本并删除现有选择.它适用于所有主流桌面浏览器:

function insertTextAtCursor(text) {
    var sel, range;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();
            range.insertNode( document.createTextNode(text) );
        }
    } else if (document.selection && document.selection.createRange) {
        document.selection.createRange().text = text;
    }
}
Run Code Online (Sandbox Code Playgroud)

UPDATE

根据评论,这里有一些用于保存和恢复选择的代码.在显示上下文菜单之前,应该将返回值存储saveSelection在变量中,然后将该变量传递到restoreSelection隐藏上下文菜单之后和插入文本之前恢复选择.

function saveSelection() {
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            return sel.getRangeAt(0);
        }
    } else if (document.selection && document.selection.createRange) {
        return document.selection.createRange();
    }
    return null;
}

function restoreSelection(range) {
    if (range) {
        if (window.getSelection) {
            sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
        } else if (document.selection && range.select) {
            range.select();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @zeel:我已经更新了你的小提琴,将光标移动到插入文本后面的位置:http://jsfiddle.net/ww3Rk/1/.在IE 9中似乎没问题. (3认同)
  • 好.在这种情况下,我建议在您要显示上下文菜单的位置存储表示选择的Range/TextRange的副本,然后在隐藏上下文菜单之后但在插入文本之前从中恢复选择. (2认同)

Mar*_*tke 12

  1. 使用 获取选择对象window.getSelection()
  2. 使用Selection.getRangeAt(0).insertNode()添加textnode。
  3. 如有必要,使用 将光标位置移动到添加的文本后面Selection.modify()。(未标准化,但 Firefox、Chrome 和 Safari 支持此功能)

    function insertTextAtCursor(text)
    {
        let selection = window.getSelection();
        let range = selection.getRangeAt(0);
        range.deleteContents();
        let node = document.createTextNode(text);
        range.insertNode(node);
    
        for(let position = 0; position != text.length; position++)
        {
            selection.modify("move", "right", "character");
        };
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • 1+ 对于“用户键入时插入/替换某物”的最简单答案。如果我正确阅读了 https://developer.mozilla.org/en-US/docs/Web/API/Selection/collapseToEnd 上的文档,则可以使用不带 for() 循环的 Selection.collapseToEnd() 。 (3认同)

ale*_*511 8

UPD:由于 ~2020 解决方案已过时(尽管它还可以工作

// <div contenteditable id="myeditable">
// const editable = document.getElementById('myeditable')
// editable.focus()
// document.execCommand('insertHTML', false, '<b>B</b>anana')
document.execCommand('insertText', false, 'banana')
Run Code Online (Sandbox Code Playgroud)

  • 来自 [MDN](https://developer.mozilla.org/en-US/docs/Web/API/document/execCommand) 关于“execCommand”:此功能已过时。尽管它在某些浏览器中仍然可以工作,但不鼓励使用它,因为它可能随时被删除。尽量避免使用它。 (2认同)
  • 我真的希望当“execCommand”过时时,浏览器会想到提出一个优雅的 API 来与可编辑内容交互。它没有发生。 (2认同)