I need to update the innerHTML of a contenteditable P element after each keystroke, in JavaScript
(no jQuery)
I can't use an input or textarea instead of the P element.
It works fine, but the caret always goes back at the beginning of the paragraph when the innerHTML is reset.
I tried to use the solutions of the other SO questions that talk about carets and contenteditable but it doesn't seem to work in my case: I want to put the caret back exactly where it was before the update of innerHTML.
p.oninput=function(){ // Get caret position c = window.getSelection(). getRangeAt(0). startOffset; console.log(c); // Update innerHTML p.innerHTML = p.innerHTML.toUpperCase(); // Place caret back // ??? }
p{ border: 1px dotted red }
<p contenteditable id=p>type here
BTW, It doesn't need to work on IE, but if you have a cross-browser solution, I'll take it too.
Thanks for your help!
Consider stepping away from the problem.
Solution 1: do not convert to uppercase until finished typing.
Solution 2: set P to monospaced font. Make the P transparent. Have div behind that updates with values as uppercase. Not sure how to show caret ... ?
Remember seeing article a year or so ago where a coding interface used similar method to have colour coded code in a textarea.
I added
const range = window.getSelection();
range.selectAllChildren(p);
range.collapseToEnd();
to your code and it seems solve the problem.
p.oninput=function(){ // Get caret position c = window.getSelection(). getRangeAt(0). startOffset; console.log(c); // Update innerHTML p.innerHTML = p.innerHTML.toUpperCase(); const range = window.getSelection(); range.selectAllChildren(p); range.collapseToEnd(); }
p{ border: 1px dotted red }
<p contenteditable id=p>type here
How late do you want to be to the party? "Yes"
If someone is still looking for a solution, maybe this works for you?
p.oninput=function(){ // Get caret position c = window.getSelection(). getRangeAt(0). startOffset; console.log(c); // Update innerHTML p.innerHTML = p.innerHTML.toUpperCase(); var range = document.createRange(); var sel = window.getSelection(); range.setStart(p.childNodes[0], c); range.collapse(true); sel.removeAllRanges(); sel.addRange(range); }
p{ border: 1px dotted red }
<p contenteditable id=p>type here
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.