1

I wrote a simple test to change the text in an editable div's content. The html structure is changed but the text is the same.

<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>

I've tried rangy like this:

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

But it report an error:

Rangy warning: Module SaveRestore: Marker element has been removed. Cannot restore selection.

Does rangy support the feature I mentioned above? If yes, how should I use it? If no, what should I do to implement that?

UPDATE: In my scenario I have to replace all the innerHTML since the text would be formatted into a very rich style. But in my case the text is always the same without the styles. Is that any possible way to record the selection and caret position and set it back? What kind of API I should use?

Jeffrey Zhao
  • 4,923
  • 4
  • 30
  • 52

1 Answers1

1

The error message is pretty descriptive of the problem, which is that Rangy's save/restore module uses hidden elements with specific IDs to mark the start and end of the selection range, meaning that if these elements are removed, the whole thing falls down.

The obvious solution is to store the selection as character positions within the visible text. This isn't as easy as it may appear, however. I'm actively working on a module to do this properly and hope to release something in the next couple of months. In the meantime, here's a naive solution that is good enough for many situations:

replace innerHTML in contenteditable div

Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • Thanks. In my scenario I have to replace all the innerHTML since the text would be formatted into a very rich style. Is that any possible way to record the selection and caret position and set it back? What kind of API I should use? – Jeffrey Zhao Mar 15 '12 at 12:25
  • @JeffreyZhao: The `saveSelection()` and `restoreSelection()` functions in the question I linked to should help. – Tim Down Mar 15 '12 at 12:44
  • It can be easily broken. Thanks anyway, I can follow your hits to investigate the APIs. – Jeffrey Zhao Mar 15 '12 at 15:49