Javascript 在内容可编辑的 div 中的光标处插入文本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2920150/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Insert text at cursor in a content editable div
提问by user314362
I have a contenteditable div where I need to insert text at the caret position,
我有一个 contenteditable div,我需要在插入符号位置插入文本,
This can be easily done in IE by document.selection.createRange().text = "banana"
这可以通过以下方式在 IE 中轻松完成 document.selection.createRange().text = "banana"
Is there a similar way of implementing this in Firefox/Chrome?
在 Firefox/Chrome 中是否有类似的实现方式?
(I know a solution exists here, but it can't be used in contenteditable div, and looks clumsy)
(我知道这里存在一个解决方案,但它不能用于 contenteditable div,而且看起来很笨拙)
Thank you!
谢谢!
回答by Tim Down
The following function will insert text at the caret position and delete the existing selection. It works in all the mainstream desktop browsers:
以下函数将在插入符号位置插入文本并删除现有选择。它适用于所有主流桌面浏览器:
function insertTextAtCaret(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;
}
}
UPDATE
更新
Based on comment, here's some code for saving and restoring the selection. Before displaying your context menu, you should store the return value of saveSelectionin a variable and then pass that variable into restoreSelectionto restore the selection after hiding the context menu and before inserting text.
根据评论,这里有一些用于保存和恢复选择的代码。在显示上下文菜单之前,您应该将 的返回值存储saveSelection在一个变量中,然后将该变量传递restoreSelection给in 以在隐藏上下文菜单后和插入文本之前恢复选择。
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();
}
}
}
回答by Martin Wantke
- Get a Selection Object with
window.getSelection(). - Use
Selection.getRangeAt(0).insertNode()to add a textnode. If necessary, move the cursor position behind the added text with
Selection.modify(). (Not standardized, but this feature is supported in Firefox, Chrome and 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"); }; }
- 使用 获取选择对象
window.getSelection()。 - 使用
Selection.getRangeAt(0).insertNode()添加textnode。 如有必要,使用 将光标位置移动到添加的文本后面
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"); }; }
回答by alex_1948511
UPD: since ~2020 solution is obsoleted(despite it can workyet)
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')
回答by Sergey Kharchishin
I have used next code to insert icons in chat msg
我已经使用下一个代码在聊天消息中插入图标
<div class="chat-msg-text" id="chat_message_text" contenteditable="true"></div>
<script>
var lastCaretPos = 0;
var parentNode;
var range;
var selection;
$(function(){
$('#chat_message_text').focus();
$('#chat_message_text').on('keyup mouseup',function (e){
selection = window.getSelection();
range = selection.getRangeAt(0);
parentNode = range.commonAncestorContainer.parentNode;
});
})
function insertTextAtCursor(text) {
if($(parentNode).parents().is('#chat_message_text') || $(parentNode).is('#chat_message_text') )
{
var span = document.createElement('span');
span.innerHTML=text;
range.deleteContents();
range.insertNode(span);
//cursor at the last with this
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
}
else
{
msg_text = $("#chat_message_text").html()
$("#chat_message_text").html(text+msg_text).focus()
}
}
</script>
回答by Alireza Mn
just an easier method with jquery:
只是一个更简单的jquery方法:
copy the entire content of the div
复制div的全部内容
var oldhtml=$('#elementID').html();
var oldhtml=$('#elementID').html();
var tobejoined='<span>hii</span>';
var tobejoined='<span>hii</span>';
//element with new html would be
//element with new html would be
$('#elementID').html(oldhtml+tobejoined);
$('#elementID').html(oldhtml+tobejoined);
simple!
简单的!


