[英]Insert text at cursor in a content editable div
我有一個 contenteditable div,我需要在插入符號位置插入文本,
這可以通過document.selection.createRange().text = "banana"
在 IE 中輕松完成
在 Firefox/Chrome 中是否有類似的實現方式?
(我知道這里有一個解決方案,但它不能用於 contenteditable 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();
}
}
}
window.getSelection()
獲取選擇對象。Selection.getRangeAt(0).insertNode()
添加一個文本節點。 如有必要,使用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"); }; }
我已經使用下一個代碼在聊天消息中插入圖標
<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>
可以使用以下代碼處理粘貼純文本。
const 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);
}
});
如果您正在使用富編輯器(如 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
}));
最后一個使用 2 種不同的方法:
data
和dataType
屬性。 這個適用於 FirefoxclipboardData
屬性。 哪個在 Chrome 中有效,但在 Firefox 中無效? https://github.com/facebook/draft-js/issues/616#issuecomment-426047799 。 雖然它應該在 Firefox 中工作,但也許我不知道如何使用它或者存在錯誤。如果要替換所有現有文本,則必須先選擇它
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})
只是使用 jquery 的一種更簡單的方法:
復制 div 的全部內容
var oldhtml=$('#elementID').html();
var tobejoined='<span>hii</span>';
//element with new html would be
$('#elementID').html(oldhtml+tobejoined);
簡單的!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.