在contenteditable div(包括标签)中获取插入符号的位置

我有一个contenteditable div我有多个标签(br,b,u,i)和文本,我需要得到相对于div的插入符号位置,包括所有的标签。

例如:

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

如果光标位于g和h之间,我需要插入符号位置为14.问题是使用treeWalkerfind的方法在这种情况下不起作用。 大胆的标签没有find…可能是因为它没有closures。 我也尝试了几种方法,但仍然没有运气。

我需要它在Firefox中工作。 谢谢。

你尝试过吗? 获取范围的开始和结束偏移量相对于其父容器

直接链接到jsfiddle: https ://jsfiddle.net/TjXEG/1/

function代码:

 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; 

只是不得不这样做,所以有一些工作的解决scheme(可能需要一些testing)

基本的想法是:

  1. 使用此方法获取textContent位置: 在包含HTML内容的contentEditable区域中获取插入(光标)位置

  2. 迭代元素的innerHTML到textContent位置

  3. 如果遇到html标签或实体,遍历它直到正常的字符,然后继续

示例代码在这里:

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