【问题标题】:How to get the selected text position in a html contenteditable div tag?如何在 html contenteditable div 标签中获取选定的文本位置?
【发布时间】:2020-03-14 13:31:23
【问题描述】:

我需要选定的文本位置区域,这是我在下面的文本区域中完成的:

//my textarea
let textarea = document.getElementById('textarea');

textarea.addEventListener('mouseup', function(){
  console.log(this.selectionStart); //return integer
})

这完全适用于 textarea 但不适用于 contentEditable div 标签,而不是返回整数值,它返回未定义,为什么以及如何在 contenteditable div 标签中获取选定的文本位置?

//myDiv
<div id="textarea" contenteditable="true">
   <p> I am on </p>
</div>

我需要一个纯 javascript 解决方案,而不是 jquery。

【问题讨论】:

  • 你在尝试window.getSelection().toString() 吗?

标签: javascript


【解决方案1】:

获取所选位置

您可以使用文档的范围观察器检索内容可编辑 div 的选定位置。 API 与纹理元素略有不同。注意:类似(也许更好)的解决方案可以是 found here(来源:Tim Down)。

// Step 1: Retrieve elements
let textarea = document.querySelectorAll('.textarea');

// Step 2: Bind events
textarea.forEach(txt=>{
  txt.addEventListener('mouseup', eventHandler) 
  txt.addEventListener('keyup', eventHandler)
})
function eventHandler(e){ getPosition(e.target) }


// Step 3: Determine cursor positions
function getPosition(el){
  let position = {start:0,end:0};
  let selection = document.getSelection();
  
  if (el.matches('textarea')){
    let offset = 1
    position.start = el.selectionStart + offset
    position.end = el.selectionEnd + offset
  }
  else {
    if (selection.rangeCount){
      let range = selection.getRangeAt(0);
      let range2 = range.cloneRange()  // don't mess with visible cursor
      range2.selectNodeContents(el)    // select content
      position.start = range.startOffset
      position.end = range.endOffset
    }
  }
  
  console.log(position.start, position.end)
}
<textarea class="textarea">
I am on
</textarea>

<div class="textarea" contenteditable="true">
   <p> I am on </p>
</div>

检索选定的文本

这稍微偏离了位置,但确实有助于识别选择。注意:该示例需要选择多个字符,而不仅仅是单击元素。

//my textarea
let textarea = document.querySelectorAll('.textarea');

textarea.forEach(txt=>txt.addEventListener('mouseup', function(){
  let sel = document.getSelection()
  console.log(sel.toString())
}))
<textarea class="textarea">
I am on
</textarea>

<div class="textarea" contenteditable="true">
   <p> I am on </p>
</div>

查找选择的位置

找到选择文本后,search() 可用于查找位置。

//my textarea
let textarea = document.querySelectorAll('.textarea');

textarea.forEach(txt=>txt.addEventListener('mouseup', function(e){
  let textbox = e.target;
  let selection = document.getSelection().toString()
  let position = textbox.textContent.search(selection)
  if(position)
    console.log(`"${selection}":`, position)
}))
<textarea class="textarea">
I am on
</textarea>

<div class="textarea" contenteditable="true">
   <p> I am on </p>
</div>

【讨论】:

  • 不确定投反对票的原因,但我会尝试用更多信息更新(或删除)答案。否则,请允许我解决您的疑虑
  • 很好的解决方案 @mike 我正在将您的想法添加到我的代码中。就像一个注释,最后一部分Find Position 有一个小问题,如果所选短语在元素中,不止一次。代码总是返回第一个位置。
【解决方案2】:

试试这个:

<html>

<body>
    <div id="textarea" contenteditable="true">
        <p>I am on dsvsdvsdv vsdvdsvds sddvdsvds vdsdds sdvdsvdsv vdsvdsvds dsvdsvdsvdsv vsdvdsv sddvsdvds vdsvdsvdsv dsvdefwfs</p>
    </div>
    <script>
        function selection() {
            if (window.getSelection)
                return window.getSelection();
        }

        let textarea = document.getElementById('textarea');

        textarea.addEventListener('mouseup', function () {
            console.log(selection())
            console.log(textarea.innerText.indexOf(selection()))
        })
    </script>
</body>

</html>

这非常有效:http://jsfiddle.net/xm0Lshdb/

【讨论】:

    【解决方案3】:

    您可以使用Selection API 获取页面中的任何选定文本。

    此 API 目前处于工作草案状态。

    这是一个工作示例:

    document.addEventListener('selectionchange', () => {
      console.log("Text :", document.getSelection().toString());
      console.log("Position:", document.getSelection().focusOffset);
    });
    

    【讨论】:

      猜你喜欢
      • 2013-08-28
      • 1970-01-01
      • 2018-07-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-12
      • 1970-01-01
      • 2011-03-08
      相关资源
      最近更新 更多