Insert text at cursor in a content editable div

user314362 picture user314362 · May 27, 2010 · Viewed 63.3k times · Source

I have a contenteditable div where I need to insert text at the caret position,

This can be easily done in IE by document.selection.createRange().text = "banana"

Is there a similar way of implementing this in Firefox/Chrome?

(I know a solution exists here , but it can't be used in contenteditable div, and looks clumsy)

Thank you!

Answer

Tim Down picture Tim Down · May 28, 2010

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();
        }
    }
}