Maintain cursor position in contenteditable div

dom, javascript

Solution

If the text the user sees remains the same (which your question seems to imply is the case), you could use a character offset-based solution. I've posted some code for that elsewhere on Stack Overflow:

https://stackoverflow.com/a/13950376/96100

I also answered a related question quite recently:

jQuery: Convert text URL to link as typing

Problem

First of all, this is similar to these: Editing Iframe Content in IE - problem in maintaining text selection How to get caret position within contenteditable div with html child elements? Basically, I'm writing something similar to the new tweet editor in twitter. Inside a `div` with `contentEditable` set on, I am parsing the text. When I detect what I think is a URL, I strip that text out and enter into an `<a>` tag inside the div (e.g. entered message of `go to www.google.com` becomes `Go to <a href='..'>www.google.com</a>`. BUT, the caret position is lost when I do that. Using the suggestion by @Tim-Down in those other SO posts will only work as long as you don't edit the DOM (as he says). I AM editing the DOM, so the caret position is lost. Is it possible (ideally without using the Rangy library referenced) to achieve this by working on the current code. The code that I have at the moment (from the other SO posts): ``` var saveSelection, restoreSelection; if (window.getSelection) { // IE 9 and non-IE saveSelection = function(win) { var sel = win.getSelection(), ranges = []; if (sel.rangeCount) { for (var i = 0, len = sel.rangeCount; i < len; ++i) { ranges.push(sel.getRangeAt(i)); } } return ranges; }; restoreSelection = function(win, savedSelection) { var sel = win.getSelection(); sel.removeAllRanges(); for (var i = 0, len = savedSelection.length; i < len; ++i) { sel.addRange(savedSelection[i]); } }; } else if (document.selection && document.selection.createRange) { // IE <= 8 saveSelection = function(win) { var sel = win.document.selection; return (sel.type != "None") ? sel.createRange() : null; }; restoreSelection = function(win, savedSelection) { if (savedSelection) { savedSelection.select(); } }; } ``` And I use it like this: ``` $('div').on('keyup paste', function(e) { var ranges = saveSelection(window); var newContent = /* Get the new HTML content */; $('div').html(newContent); restoreSelection(window, ranges); }); ```

Original source

Related problems