首页 文章

获得包括标签在内的可信赖div中的插入位置

提问于
浏览
7

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

例如:

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

如果光标在g和h之间,我需要插入位置为14.问题是找到的使用treeWalker的方法在这种情况下不起作用 . 找不到粗体标签......可能是因为它没有关闭 . 我也尝试了几种方法,但仍然没有运气 .

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

2 回答

  • 3

    你试过这个吗? Get a range's start and end offset's relative to its parent container

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

    功能码:

    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;
    
  • 19

    只是必须这样做,所以有一些工作的解决方案(可能需要一些测试)

    基本思路是:

    示例代码:

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

相关问题