我有一个可编辑的div,需要在光标位置插入文本,
在IE中,可以很容易地通过 document.selection.createRange().text = "banana"
实现
在Firefox/Chrome中有类似的实现方式吗?
(我知道这里有一个解决方案,但无法在可编辑的div中使用,并且看起来很笨拙)
谢谢!
我有一个可编辑的div,需要在光标位置插入文本,
在IE中,可以很容易地通过 document.selection.createRange().text = "banana"
实现
在Firefox/Chrome中有类似的实现方式吗?
(我知道这里有一个解决方案,但无法在可编辑的div中使用,并且看起来很笨拙)
谢谢!
以下函数将在插入符位置插入文本并删除现有的选择内容。它适用于所有主流桌面浏览器:
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;
}
}
更新
根据评论,这里有一些保存和恢复选择的代码。在显示上下文菜单之前,您应该将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();
}
}
}
function insertTextAtCursor(text) { var range, sel = rangy.getSelection(); if (sel.rangeCount) { range = sel.getRangeAt(0); range.insertNode( document.createTextNode(text) ); } }
- Tim Downwindow.getSelection()
.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");
};
}
selection.modify("move", "right", "character");
- DeeexecCommand
时,浏览器能够考虑提出一种优雅的API来与可编辑内容进行交互。但事实并非如此。 - Frenchcooc<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>
如果你正在使用富文本编辑器(如DraftJs),但没有访问其API的权限(例如从扩展程序进行修改),以下是我发现的解决方案:
beforeinput
事件,这是推荐的方式,大多数编辑器都支持target.dispatchEvent(new InputEvent("beforeinput", {
inputType: "insertText",
data: text,
bubbles: true,
cancelable: true
}))
paste
事件const data = new DataTransfer();
data.setData(
'text/plain',
text
);
target.dispatchEvent(new ClipboardEvent("paste", {
dataType: "text/plain",
data: text,
bubbles: true,
clipboardData: data,
cancelable: true
}));
data
和dataType
属性。这个在Firefox中有效。clipboardData
属性。这个在Chrome中有效,但在Firefox中无效?https://github.com/facebook/draft-js/issues/616#issuecomment-426047799。尽管应该在Firefox中有效,也许我不知道如何使用它或者有一个bug。如果你想替换所有现有的文本,你必须先选择它。
function selectTargetText(target) {
const selection = window.getSelection();
const range = document.createRange();
range.selectNodeContents(target);
selection.removeAllRanges();
selection.addRange(range);
}
selectTargetText(target)
// wait for selection before dispatching the `beforeinput` event
document.addEventListener("selectionchange",()=>{
target.dispatchEvent(new InputEvent("beforeinput", {
inputType: "insertText",
data: text,
bubbles: true,
cancelable: true
}))
},{once: true})
target
和 text
,例如 document.getElementById('myId')
和 "sometext"
。target
必须是富文本编辑器内部的任何 HTML 元素。 - Madacolconst editorEle = document.getElementById('editor');
// Handle the `paste` event
editorEle.addEventListener('paste', function (e) {
// Prevent the default action
e.preventDefault();
// Get the copied text from the clipboard
const text = e.clipboardData
? (e.originalEvent || e).clipboardData.getData('text/plain')
: // For IE
window.clipboardData
? window.clipboardData.getData('Text')
: '';
if (document.queryCommandSupported('insertText')) {
document.execCommand('insertText', false, text);
} else {
// Insert text at the current position of caret
const range = document.getSelection().getRangeAt(0);
range.deleteContents();
const textNode = document.createTextNode(text);
range.insertNode(textNode);
range.selectNodeContents(textNode);
range.collapse(false);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
});
使用jQuery更简单的方法:
复制整个div的内容
var oldhtml = $('#elementID').html();
var tobejoined = '<span>hii</span>';
//具有新HTML的元素将是
$('#elementID').html(oldhtml+tobejoined);
简单!