我们先看一下效果图:
这是搜索关键字cfg
时,会自动匹配到config
方法
同样,我们再看另一个例子
通过关键字bi
会匹配到好几个结果
这个和一些编辑器的搜索功能很像,比如sublime text,不需要知道关键字的完整拼写,只需要知道其中的几个字母即可。
那么这个功能在前端我们如何去实现呢?
不考虑性能的话,我们可以用正则简单实现如下:
把关键字拆分,加入(.?),如cfg最终为 (.?)(c)(.?)(f)(.?)(g)(.*?),然后拿这个正则去测试要搜索的列表,把符合要求的选项给拿出来即可
考虑到要高亮结果,我们还要生成对应的替换表达式,最后的函数如下
var escapeRegExp = /[\-#$\^*()+\[\]{}|\\,.?\s]/g;
var KeyReg = (key) => {
var src = ['(.*?)('];
var ks = key.split('');
if (ks.length) {
while (ks.length) {
src.push(ks.shift().replace(escapeRegExp, '\\$&'), ')(.*?)(');
}
src.pop();
}
src.push(')(.*?)');
src = src.join('');
var reg = new RegExp(src, 'i');
var replacer = [];
var start = key.length;
var begin = 1;
while (start > 0) {
start--;
replacer.push('$', begin, '($', begin + 1, ')');
begin += 2;
}
replacer.push('$', begin);
info = {
regexp: reg,
replacement: replacer.join('')
};
return info;
};
调用KeyReg
把关键字传入,拿返回值的regexp
去检测搜索的列表,把符合的保存下来即可。
到目前为止我们只实现了搜索功能,按更优的体验来讲,在搜索结果中,要优先把相连匹配的放在首位,如bi
关键字,要把bind
结果放到beginUpdate
前面。第二个截图是有优化的地方的。
要完成这个功能,我们使用KeyReg
返回值中的replacement
,用它进行检测,把结果中长度最长的放前面即可,这块代码以后有时间再补充
2018.5.31
今天重构了下,增加了结果排序,完整的代码及使用示例如下