Insert text at cursor in a content editable div
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 saveSelection
in a variable and then pass that variable into restoreSelection
to restore the selection after hiding the context menu and before inserting text.
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(); } }}
- 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"); };}