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);
});
` and block elements. – Tim Down Apr 25 '13 at 09:13