I'm inserting an element into a contentEditable div but the browser sets the position of the cursor before the inserted element. Is it possible to set the cursor right after the inserted element so that the user keeps typing without having to re-adjust the cursor position?
The following function will do it. DOM Level 2 Range objects make this easy in most browsers. In IE, you need to insert a marker element after the node you're inserting, move the selection to it and then remove it.
Live example: http://jsfiddle.net/timdown/4N4ZD/
Code:
function insertNodeAtCaret(node) { if (typeof window.getSelection != "undefined") { var sel = window.getSelection(); if (sel.rangeCount) { var range = sel.getRangeAt(0); range.collapse(false); range.insertNode(node); range = range.cloneRange(); range.selectNodeContents(node); range.collapse(false); sel.removeAllRanges(); sel.addRange(range); } } else if (typeof document.selection != "undefined" && document.selection.type != "Control") { var html = (node.nodeType == 1) ? node.outerHTML : node.data; var id = "marker_" + ("" + Math.random()).slice(2); html += '<span id="' + id + '"></span>'; var textRange = document.selection.createRange(); textRange.collapse(false); textRange.pasteHTML(html); var markerSpan = document.getElementById(id); textRange.moveToElementText(markerSpan); textRange.select(); markerSpan.parentNode.removeChild(markerSpan); } }
Alternatively, you could use my Rangy library. The equivalent code there would be
function insertNodeAtCaret(node) { var sel = rangy.getSelection(); if (sel.rangeCount) { var range = sel.getRangeAt(0); range.collapse(false); range.insertNode(node); range.collapseAfter(node); sel.setSingleRange(range); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With