文本搜索后如何设置setSelection?

时间:2019-04-26 12:49:14

标签: quill

我正在尝试向Quill添加搜索功能,并希望突出显示它找到的文本。我在获取找到的文本的范围索引时遇到了麻烦,很可能是我没有使用正确的方法。

到目前为止,我使用getContents()获得了文本,并且可以通过遍历行找到匹配项。但是,我无法为setSelection()找到正确的索引位置。第二个问题是我希望窗口滚动到找到所选内容的位置,而不是滚动到视图中。

...
myKeyPhrases = ['obvious', 'orange', 'apple'];

var myDelta = editor.getContents();
myDelta.eachLine((line, attributes, i) => {

    mytext = line.filter((op) => typeof op.insert === 'string').map((op) => op.insert).join('');
    mytext = mytext.toLowerCase();

    ndx = isKeyPhraseFound(mytext, myKeyPhrases); 
    if (ndx >= 0){
        // The code finds the matches OK to here.
        // The next 4 lines don't get the correct range and scroll.
        index = i;
        editor.focus();
        editor.setSelection(index, 1, Quill.sources.USER); 
        editor.scrollIntoView();
        return index;
    }
});

我希望得到的结果是,将选择找到的文本匹配项,并滚动窗口,以便显示选择内容。实际结果是选择了错误的文本,并且没有滚动窗口以查看选择。

1 个答案:

答案 0 :(得分:0)

您基本上就在那儿。我怀疑您的问题是您正在过滤出块元素,其行为类似于Quill的getText方法。根据文档:

  

由于省略了非字符串内容,因此返回的字符串长度可能比getLength返回的编辑器长度短。

这是因为非文本元素的长度通常为1,因此对于您忽略的每个元素,索引的偏移量将为1。

一个简单的解决方法是用长度为1的换行符替换所有非文本元素,并增加了搜索失败的附加好处(除非您让用户使用换行符进行搜索-也许您会可以选择其他特殊字符,例如控制字符)。

以下方法应返回长度与quill.getLength相匹配的羽毛笔内容的纯文本表示,因此应该可以使用所需的任何JavaScript文本搜索方法(例如,indexOf简单搜索)。

function textContents() {
  return quill.getContents().ops
    .reduce((text, op) => {
      if (typeof op.insert === 'string') {
        // If the op is a string insertion, just concat
        return text + op.insert;
      } else {
        // Otherwise it's a block. Represent this as a newline,
        // which will preserve the length of 1, and also prevent
        // searches matching across the block
        return text + '\n';
      }
    }, '');

}

下面是一个粗略的示例:https://codepen.io/alecgibson/pen/GLVzPb