Get caret position in contenteditable div including tags

好久不见. 提交于 2019-11-26 20:33:16

Have you tried this? Get a range's start and end offset's relative to its parent container

Direct link to the 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;
YangombiUmpakati

just had to do this so there is some working solution (some testing may be required)

basic idea is to:

  1. get textContent position using this method: Get caret (cursor) position in contentEditable area containing HTML content

  2. iterate through innerHTML of an element to the textContent position

  3. if html tag or entity is encountered, iterate through it until normal char, then continue

sample code here:

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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!