如何在使用selectNodeContents时选择带有其内容的HTML标签?

8

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

   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 <b>jony</b>, whats goin on in the | party *光标用字符|表示。
执行getMeCurPos(ele)返回:30,但它应该返回37。它没有计算b标签。

有人有答案吗…… - Tanya Arora
一直在尝试设置你的代码。你能提供一个 jsfiddle 来展示你当前代码的功能版本吗? - asifrc
有关这个问题,您有什么想法吗? - Finder
3个回答

1
你可以创建一个临时的 div,将你的 preCaretRange 放入其中,并在其中使用 textContentinnerText。这不会计算 HTML 的长度,而是计算其周围的文本。
 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;
       }                        
}

请参见此代码片段:this fiddle

仍然只返回文本计数,而不计算标签。 请参见此fiddle - Tanya Arora
@TanyaArora 好的,我完全不明白你的问题。我以为是相反的情况。我正在研究它。 - Shikiryu
@TanyaArora 使用文本区域可以解决这个问题:http://jsfiddle.net/KLEbW/1/ - Shikiryu

1
要同时获取选择的文本和DOM节点,您可以在Javascript selection-range中使用cloneContents()。HTML如下:

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;
  }
}
<p contenteditable="true" id="test" onclick="alert(getMeCurPos(this))">Test1<br>Test2<br>Test3<br>Test4</p>
<br>
Cloned: <span id="cloned"></span>


0
我已经从这篇文章中取得了代码:使用单击选择所有DIV文本
            <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);
                    }
                }
            </script>

            <div id="selectable" onclick="selectText('selectable')">http://example.com/page.htm</div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接