首页 > 解决方案 > 如何在 html contenteditable div 标签中获取选定的文本位置?

问题描述

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

//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 中。

标签: javascript

解决方案


获得选定的职位

您可以使用文档的范围观察器检索内容可编辑 div 的选定位置。API 与纹理元素略有不同。注意:可以在此处找到类似(也许更好)的解决方案(来源: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>


推荐阅读