繁体   English   中英

使用 javascript 在内容可编辑 div 内进行多行选择的字符 position

[英]character position of a multi-line selection within a content editable div using javascript

请看一下这个小提琴:

https://jsfiddle.net/darrengates/jwx41Lkz/

在这个例子中,我有一个 3 行的可编辑 div。 我正在尝试获取选择的起始字符 position 和结束字符 position。

这似乎只适用于第一行。 如果我突出显示超过 1 行,则值不正确(请参阅注释以获取解释)。

当它跨越多行时,如何获得启动和结束字符position的选择? (即,字符 position 从整个 div 的第一个字母开始,例如,“第二行”中的“s”大约是字符 position 11)。

这是我到目前为止所拥有的(可在小提琴中运行):

<div id="test" contenteditable="true" class="selecttest">
first line<br />
second line<br />
third line
</div>
.selecttest {
  width: 400px;
  height: 200px;
  border: 1px solid black;
  padding: 5px;
  font-size: 20px;
}
function getSelection() {

    const sel = document.getSelection() || window.getSelection();

    // note: if I highlight the 2nd and 3rd lines
    // start and end values are 1, 11
    // they should be about 11 and 22 (or so)
    // on account of the existence of the first line
  
    let start = sel.baseOffset
    let end = sel.extentOffset
  
    // if selected from right to left, reverse...
    if ( start > end ) {
      const temp = start;
      start = end;
      end = temp;
    }
  
    console.log('start, end', start, end)
}

$("#test").on('mouseup', function() {
    getSelection();
})

似乎有很多与获取选定文本相关的 SO 帖子,但与获取选定字符位置相关的答案在选择多行时都失败了。

由于您想在一个范围内测量 position,您应该使用一个范围 object 而不是选择 object。

关于此代码笔的建议> https://codepen.io/aSH-uncover/pen/ExEdXwy

主要技巧是解决范围是否在同一个容器内的两种情况:)

function getSelection() {
  const sel = document.getSelection() || window.getSelection();

  const range = sel.getRangeAt(0)
  
  let rangeContainer = range.commonAncestorContainer
  let same = false
  if (rangeContainer === range.startContainer) {
    same = true
    rangeContainer = range.startContainer.parentElement
  }
  
  let start = -1
  let end = -1
  
  const list = rangeContainer.childNodes
  let offset = 0
  for (let i = 0 ; i < list.length ; i++) {
    const current = list[i]
    if (current === range.startContainer) {
      start = offset + range.startOffset
      if (same) {
        end = offset + range.endOffset
        break
      }
    } else if (current === range.endContainer) {
      end = offset + range.endOffset
      break
    }
    if (current.nodeName === '#text') {
      offset += current.length
    }
  }
  
  console.log('start, end', start, end)
}

编辑:如果你想支持更复杂的文本(比如带有跨度的 div),你将不得不改进这个 function 并包括一些递归的东西:)

JavaScript:多线选择开启<textarea>&lt;i&gt;field&lt;/div&gt;&lt;/i&gt;&lt;b&gt;字段&lt;/div&gt;&lt;/b&gt;</textarea><div id="text_translate"><p> 你好,</p><p> Mozilla 的 Firefox 浏览器允许在默认的 HTML &lt;textarea&gt;字段上进行多行选择,使用常见的方式是在使用鼠标选择一些文本的同时按 CTRL。</p><p> 我的问题:是否可以接收相应的选择数据?</p><p> 我已经尝试在全局window object 上使用getSelection()方法,但它什么都不包含。 HTMLTextAreaElement本身的selectionStart和selectionEnd属性也只包含最后一次选择,我也没有找到任何其他的 - 可能 Firefox 拥有 - 允许我访问它们的属性或函数。</p><p> 当然,也可以在相应的&lt;textarea&gt;字段上使用select事件创建自己的侦听器。 但是,我想这是一个可怕的想法,如果不是所有可能的程序(以任何方式操纵或更改选择)都被真正覆盖并走上正轨,那么这会导致错误的信息。</p><p> 谢谢。</p></div>

[英]JavaScript: Multi-Line Selection on <textarea> field

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在选择的每一行上,将字符添加到Codemirror中的多行选择中 JavaScript:多线选择开启<textarea>&lt;i&gt;field&lt;/div&gt;&lt;/i&gt;&lt;b&gt;字段&lt;/div&gt;&lt;/b&gt;</textarea><div id="text_translate"><p> 你好,</p><p> Mozilla 的 Firefox 浏览器允许在默认的 HTML &lt;textarea&gt;字段上进行多行选择,使用常见的方式是在使用鼠标选择一些文本的同时按 CTRL。</p><p> 我的问题:是否可以接收相应的选择数据?</p><p> 我已经尝试在全局window object 上使用getSelection()方法,但它什么都不包含。 HTMLTextAreaElement本身的selectionStart和selectionEnd属性也只包含最后一次选择,我也没有找到任何其他的 - 可能 Firefox 拥有 - 允许我访问它们的属性或函数。</p><p> 当然,也可以在相应的&lt;textarea&gt;字段上使用select事件创建自己的侦听器。 但是,我想这是一个可怕的想法,如果不是所有可能的程序(以任何方式操纵或更改选择)都被真正覆盖并走上正轨,那么这会导致错误的信息。</p><p> 谢谢。</p></div> 如何使用JavaScript将具有变量的多行html输出到div中? 替换WKWebView中DIV标签的多行文本内容? 根据字符偏移在可编辑的 div 中设置 cursor position 从中提取多行javascript内容<script> tag using Scrapy 在可通过角度编辑的div内容中找到字符中的插入符位置 如何在多行警报框中调用Javascript函数? 如何使用Javascript获取多行文本框中的行号 Javascript 中的多行警报
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM