Как восстановить позицию выделения / каретки при изменении структуры html редактируемого элемента div? - PullRequest
1 голос
/ 15 марта 2012

Я написал простой тест для изменения текста в редактируемом содержимом div. Структура HTML изменена, но текст такой же.

<html xmlns="http://www.w3.org/1999/xhtml" > 
<head> 
    <title>Hello</title> 
    <script type="text/javascript" src="rangy-core.js"></script> 
    <script type="text/javascript" src="rangy- 
selectionsaverestore.js"></script> 
</head> 
<body>

<div id="show" class="code" contenteditable="true"><span 
style="color:red">12345</span>12345</div> 

<script type="text/javascript">

window.setTimeout(function () { 
    // save selection / caret position
    var show = document.getElementById("show"); 
    show.innerHTML = "1234512345"; 
    // restore select / caret position
}, 5000) 

</script> 

</body> 
</html>

Я пробовал Ранги , как это:

var s = rangy.saveSelection(); 
var show = document.getElementById("show"); 
show.innerHTML = "1234512345"; 
rangy.restoreSelection(s); 

Но сообщается об ошибке:

Предупреждение Rangy: Модуль SaveRestore: элемент Marker был удален. Не удается восстановить выделение.

Поддерживает ли rangy функцию, о которой я говорил выше? Если да, то как мне его использовать? Если нет, что я должен сделать, чтобы реализовать это?

ОБНОВЛЕНИЕ: В моем сценарии я должен заменить весь innerHTML, так как текст будет отформатирован в очень богатый стиль. Но в моем случае текст всегда одинаков без стилей. Это какой-нибудь возможный способ записать выбор и позицию каретки и установить ее обратно? Какой API мне следует использовать?

1 Ответ

1 голос
/ 15 марта 2012

Сообщение об ошибке довольно точно описывает проблему, заключающуюся в том, что модуль сохранения / восстановления Rangy использует скрытые элементы с определенными идентификаторами, чтобы отметить начало и конец диапазона выбора, что означает, что если эти элементы будут удалены, то все это будет вниз.

Очевидное решение состоит в том, чтобы сохранить выделение как позиции символов в видимом тексте. Однако это не так просто, как может показаться. Я активно работаю над модулем, чтобы сделать это правильно, и надеюсь выпустить что-нибудь в ближайшие пару месяцев. А пока вот наивное решение, которое достаточно для многих ситуаций:

заменить innerHTML в contenteditable div

...