rangy
rangy copied to clipboard
Contenteditable: Cannot restore selection after setting innerHTML programmatically
If I try to restore the cursor in a contentEditable div after changing innerHTML, it doesn't work and I get the following warning:
Rangy warning: Module SaveRestore: Marker element has been removed. Cannot restore selection.
My code looks like this:
import rangy from 'rangy';
import 'rangy/lib/rangy-selectionsaverestore';
import React from 'react';
import ReactContentEditable from 'react-contenteditable';
function ContentEditable({ content, isEditable = true, onChange }) {
return (
<div>
<ReactContentEditable
disabled={!isEditable}
html={content}
onChange={handleChange(onChange, maxLength)} />
</div>
);
}
function handleChange(onChange) {
return (event) => {
const value = event.target.value;
// some logic here...
const savedSelection = rangy.saveSelection(event.nativeEvent.target);
event.nativeEvent.target.innerHTML = doSomethingWithTheValue(value);
rangy.restoreSelection(savedSelection);
}
}
After reading http://stackoverflow.com/questions/5595956/replace-innerhtml-in-contenteditable-div I was hopeful to get it running this way.
Any suggestions?
@christianharke did you manage to get this working?
@KokoChris nope, still open issue
got the same problem? any chance you fixed it?
Sorry for the late response. We worked around the problem without using rangy (we stopped setting innerHtml directly, using react-contenteditable now). For completeness... We reset our cursor position like this now:
/**
* Sets the cursor position on the provided element
*
* @example (if no previous cursor position is known)
* Cursor is set to the end of the provided element
*
* @example (if givenCursorPosition=10)
* Cursor is set to position 10 in the provided element
*
* @param {Element} element - The DOM element on which to set the cursorPosition
* @param {number} givenCursorPosition - The last known cursor position for this element
* @returns {undefined}
*/
function setCursorPosition(element, givenCursorPosition = null) {
const selection = window.getSelection();
if (selection && element) {
const cursorPosition = givenCursorPosition
? Math.min(givenCursorPosition, element.length)
: element.length;
selection.removeAllRanges();
const range = document.createRange();
range.setStart(element, cursorPosition);
selection.addRange(range);
}
}