Как получить позицию каретки в contenteditable div с дочерними элементами html?

Я работаю с contenteditable div, у которого будет возможность иметь встроенные элементы html, такие как теги в текстовом потоке.

В определенные моменты мне нужно захватить позицию каретки, но обнаружил, что с примером кода возвращаемая позиция неверна, если каретка находится после дочернего элемента html.

Мне нужно решение для перекрестного браузера, которое позволит мне сохранить позицию каретки, чтобы можно было восстановить вторую секунду позже даже с наличием элементов html в текстовом потоке.

Пример: http://jsfiddle.net/wPYMR/2/

Ответ 1

Я ответил на очень похожий вопрос: Редактирование содержимого Iframe в IE - проблема в сохранении выбора текста

Вот немного упрощенная версия этого ответа:

Если вы не меняете содержимое элемента, пригодного для контента, тогда будут выполняться следующие функции. Вызовите saveSelection(), прежде чем делать то, что вам нужно сделать, и restoreSelection() после этого. Если вы меняете контент, я бы предложил использовать Rangy библиотеку сохранить/восстановить выбор.

var saveSelection, restoreSelection;
if (window.getSelection) {
    // IE 9 and non-IE
    saveSelection = function() {
        var sel = window.getSelection(), ranges = [];
        if (sel.rangeCount) {
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                ranges.push(sel.getRangeAt(i));
            }
        }
        return ranges;
    };

    restoreSelection = function(savedSelection) {
        var sel = window.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() {
        var sel = document.selection;
        return (sel.type != "None") ? sel.createRange() : null;
    };

    restoreSelection = function(savedSelection) {
        if (savedSelection) {
            savedSelection.select();
        }
    };
}

Пример использования:

var sel = saveSelection();
// Do stuff here
restoreSelection(sel);