Get carriage position in contenteditable div, including tags

I have a contenteditable div in which I have several tags (br, b, u, i) and text, and I need to get the caret position relative to the div, including all the tags.

For example:

<div id="h" contenteditable="true">abc<b>def<br>ghi</b>jkl</div> 

If the cursor is between g and h, I need the carriage position to be 14. The problem is that the found methods that use treeWalker do not work in this case. Bold tag not found ... perhaps because it is not closed. In addition, I tried several methods, but still no luck.

I need it to work in Firefox. Thanks.

+7
source share
2 answers

Have you tried this? Get the offset of the beginning and end of the range relative to its parent container

Direct link to jsfiddle: https://jsfiddle.net/TjXEG/1/

Function Code:

 function getCaretCharacterOffsetWithin(element) { var caretOffset = 0; if (typeof window.getSelection != "undefined") { var range = window.getSelection().getRangeAt(0); var preCaretRange = range.cloneRange(); preCaretRange.selectNodeContents(element); preCaretRange.setEnd(range.endContainer, range.endOffset); caretOffset = preCaretRange.toString().length; } else if (typeof document.selection != "undefined" && document.selection.type != "Control") { var textRange = document.selection.createRange(); var preCaretTextRange = document.body.createTextRange(); preCaretTextRange.moveToElementText(element); preCaretTextRange.setEndPoint("EndToEnd", textRange); caretOffset = preCaretTextRange.text.length; } return caretOffset; } function showCaretPos() { var el = document.getElementById("test"); var caretPosEl = document.getElementById("caretPos"); caretPosEl.innerHTML = "Caret position: " + getCaretCharacterOffsetWithin(el); } document.body.onkeyup = showCaretPos; document.body.onmouseup = showCaretPos; 
+20
source

it just needed to be done so that there was some kind of working solution (some testing may be required)

The basic idea is as follows:

code example:

 function getHTMLCaretPosition(element) { var textPosition = getCaretPosition(element), htmlContent = element.innerHTML, textIndex = 0, htmlIndex = 0, insideHtml = false, htmlBeginChars = ['&', '<'], htmlEndChars = [';', '>']; if (textPosition == 0) { return 0; } while(textIndex < textPosition) { htmlIndex++; // check if next character is html and if it is, iterate with htmlIndex to the next non-html character while(htmlBeginChars.indexOf(htmlContent.charAt(htmlIndex)) > -1) { // console.log('encountered HTML'); // now iterate to the ending char insideHtml = true; while(insideHtml) { if (htmlEndChars.indexOf(htmlContent.charAt(htmlIndex)) > -1) { if (htmlContent.charAt(htmlIndex) == ';') { htmlIndex--; // entity is char itself } // console.log('encountered end of HTML'); insideHtml = false; } htmlIndex++; } } textIndex++; } //console.log(htmlIndex); //console.log(textPosition); // in htmlIndex is caret position inside html return htmlIndex; } 
+3
source

All Articles