Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set caret position right after the inserted element in a contentEditable div

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?

like image 848
Elie Avatar asked Jan 29 '11 02:01

Elie


Video Answer


1 Answers

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);     } } 
like image 185
Tim Down Avatar answered Sep 22 '22 22:09

Tim Down