文本搜索后如何设置选择?
How do I setSelection after a text search?
我正在尝试向 Quill 添加搜索功能,并希望突出显示它找到的文本。我在获取它找到的文本的范围索引时遇到问题,很可能我没有使用正确的方法。
到目前为止,我使用 getContents() 获取文本并且可以通过遍历行找到匹配项。但是,我无法找到 setSelection() 的正确索引位置。第二个问题是我希望 window 滚动到找到选择的位置,但它没有滚动到视图中。
...
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;
}
});
我想要的结果是选择找到的文本匹配项,然后滚动 window 以便显示选择。实际结果是选择了错误的文本,window 没有滚动查看选择。
你基本上就在那里。我怀疑你的问题是你过滤掉了块元素,这类似于 Quill 的 getText
方法。根据文档:
Non-string content are omitted, so the returned string’s length may be shorter than the editor’s as returned by getLength
.
这是因为非文本元素的长度通常为 1,因此对于您省略的每一个元素,您的索引都会漂移 1。
一个简单的解决方法是用换行符替换任何非文本元素,换行符的长度为 1,还有导致搜索失败的额外好处(除非您让用户使用换行符搜索 - 也许然后你可以选择另一个特殊字符,如控制字符)。
以下方法应该 return 长度匹配 quill.getLength
的 Quill 内容的纯文本表示,因此应该能够使用任何 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
我正在尝试向 Quill 添加搜索功能,并希望突出显示它找到的文本。我在获取它找到的文本的范围索引时遇到问题,很可能我没有使用正确的方法。
到目前为止,我使用 getContents() 获取文本并且可以通过遍历行找到匹配项。但是,我无法找到 setSelection() 的正确索引位置。第二个问题是我希望 window 滚动到找到选择的位置,但它没有滚动到视图中。
...
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;
}
});
我想要的结果是选择找到的文本匹配项,然后滚动 window 以便显示选择。实际结果是选择了错误的文本,window 没有滚动查看选择。
你基本上就在那里。我怀疑你的问题是你过滤掉了块元素,这类似于 Quill 的 getText
方法。根据文档:
Non-string content are omitted, so the returned string’s length may be shorter than the editor’s as returned by
getLength
.
这是因为非文本元素的长度通常为 1,因此对于您省略的每一个元素,您的索引都会漂移 1。
一个简单的解决方法是用换行符替换任何非文本元素,换行符的长度为 1,还有导致搜索失败的额外好处(除非您让用户使用换行符搜索 - 也许然后你可以选择另一个特殊字符,如控制字符)。
以下方法应该 return 长度匹配 quill.getLength
的 Quill 内容的纯文本表示,因此应该能够使用任何 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