关于javascript:使用selectNodeContents时如何选择带有其内容的html标签?

How to select the html tags with their contents when using selectNodeContents?

我有这段代码,用于获取光标在可编辑div中的位置:

1
2
3
4
5
6
7
8
9
10
   function getMeCurPos(element){
       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;  
          return caretOffset;
       }                        
   }

问题在于,返回的caretOffset仅计算文本内容,而不计算html标签。 例如:

在我的可编辑div中考虑以下字符串:
Hey jony, whats goin on in the | party

*光标由|字符表示。

进行getMeCurPos(ele)返回:30,但应该返回37。 它不计算b标签


您可以创建一个临时div,您可以在其中放置preCaretRange,并可以在其中使用textContentinnerText。 这不会占用HTML长度,但会占用周围的文本。

1
2
3
4
5
6
7
8
9
10
11
12
13
 function getMeCurPos(element){
       if (typeof window.getSelection !="undefined") {
          var range = window.getSelection().getRangeAt(0);
          var preCaretRange = range.cloneRange();
          preCaretRange.selectNodeContents(element);
          preCaretRange.setEnd(range.endContainer, range.endOffset);
          var temp = document.createElement("div");
          temp.innerHTML = preCaretRange.toString();
          var sanitized = temp.textContent || temp.innerText;
          caretOffset = sanitized.length;
          return caretOffset;
       }                        
}

看到这个小提琴


为了同时以文本和DOM节点形式获得选择,可以在Javascript选择范围内使用cloneContents()
HTML如下

1
2
3
4
5
6
7
8
9
10
11
12
13
function getMeCurPos(element) {
  if (typeof window.getSelection !="undefined") {
    var range = window.getSelection();
    cloned.innerHTML = '';
    for (let i = 0; i < range.rangeCount; i++) {
      cloned.append(range.getRangeAt(i).cloneContents());
    }

    var sanitized = cloned.innerHTML;
    caretOffset = sanitized.length;
    return caretOffset;
  }
}
1
2
3
4
<p contenteditable="true" id="test" onclick="alert(getMeCurPos(this))">Test1Test2Test3Test4
</p>

Cloned: <span id="cloned"></span>


我从本文中获取了代码:
一次单击即可选择所有DIV文本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
            <script type="text/javascript">
                function selectText(containerid) {
                    if (document.selection) {
                        var range = document.body.createTextRange();
                        range.moveToElementText(document.getElementById(containerid));
                        range.select();
                    } else if (window.getSelection) {
                        var range = document.createRange();
                        range.selectNode(document.getElementById(containerid));
                        window.getSelection().addRange(range);
                    }
                }
           

            http://example.com/page.htm