如何从 contenteditable 中获取特定的选择

How to get a specific selection from contenteditable

我想做的是只为我想要的可满足输入的单词获取 selection。例如,

你好我的世界

根据上面的输入值,我只想select单词'My'并得到它的字符串值。

到目前为止,我已经编写了一个函数,它从 0 范围获取一个 selection 到插入符号,如下所示:

function selectUptoCaret(el){
    var range = window.getSelection().getRangeAt(0);
    var preCaretRange = range.cloneRange();
    preCaretRange.selectNodeContents(el);
    preCaretRange.setEnd(range.endContainer, range.endOffset);

    var sel = window.getSelection()
    sel.removeAllRanges()
    sel.addRange(preCaretRange)
  }

当我从单词 'My' 中单击 'y' 时,它 select 变成了 'Hello My'。 但同样,我只想 select 'My',而不是 'Hello My'。

我认为你大部分时间都在那里,但是突出显示插入符号左侧的所有内容的问题可能与你没有调用 preCaretRange.setStart() 的事实有关,所以它是认为开始应该是零。我稍微修改了你的函数,以使其成为 select 你的光标所在的实际单词:

function selectUptoCaret(el){
    var range = window.getSelection().getRangeAt(0);
    var preCaretRange = range.cloneRange();

    var startOffset = range.startContainer.textContent.lastIndexOf(' ', range.startOffset);
    var endOffset = range.endContainer.textContent.indexOf(' ', range.endOffset);

    preCaretRange.selectNodeContents(el);
    preCaretRange.setStart(range.startContainer, ~startOffset ? startOffset + 1: 0);
    preCaretRange.setEnd(range.endContainer, ~endOffset ? endOffset : range.endContainer.textContent.length);

    var sel = window.getSelection()
    sel.removeAllRanges()
    sel.addRange(preCaretRange)
}

我的假设是传递给 selectUptoCaretel 参数是实际的 contentEditable HTML 元素。

我的更改是:

  • 获取光标位置并获取下一个和上一个spaces
  • 的位置
  • 如果没有前面的space(由~startOffset检查确定)我们将从0开始,因为我们在第一个字
  • 如果后面没有space(由~endOffset校验决定)我们将使用全文内容,因为我们在最后一个字
  • 在我们的 preCaretRange 对象上设置 setStart 以确保我们有一个有限的起点,不一定是文本内容的开头

注意:我的三进制~startOffset ? startOffset + 1 : 0相当于说startOffset > -1 ? startOffset + 1 : 0。使用 ~ 按位运算符是检查值不是 -1 的便捷方法(因为 ~ -1 === 0)。

这现在只会 select 插入符号位置的当前单词。