有没有不依赖其它库的JavaScript自动完成库?
我正在制作一个需要保持轻量级的移动应用程序,因此不使用jQuery或类似工具。
有没有不依赖其它库的JavaScript自动完成库?
我正在制作一个需要保持轻量级的移动应用程序,因此不使用jQuery或类似工具。
这里有一个基本的 JavaScript 示例,可以修改为自动完成控件:
var people = ['Steven', 'Sean', 'Stefan', 'Sam', 'Nathan'];
function matchPeople(input) {
var reg = new RegExp(input.split('').join('\\w*').replace(/\W/, ""), 'i');
return people.filter(function(person) {
if (person.match(reg)) {
return person;
}
});
}
function changeInput(val) {
var autoCompleteResult = matchPeople(val);
document.getElementById("result").innerHTML = autoCompleteResult;
}
<input type="text" onkeyup="changeInput(this.value)">
<div id="result"></div>
.join('\\w*\\s*\\w*')
替换.join('\\w*')
将使得可以匹配来自不同单词的字母。 - ellockie对于任何在2017年以后需要简单解决方案的人,你可以使用HTML5内置的<datalist>
标签,而不是依赖JavaScript。
例如:
<datalist id="languages">
<option value="HTML">
<option value="CSS">
<option value="JavaScript">
<option value="Java">
<option value="Ruby">
<option value="PHP">
<option value="Go">
<option value="Erlang">
<option value="Python">
<option value="C">
<option value="C#">
<option value="C++">
</datalist>
<input type="text" list="languages">
https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/datalist
Array.prototype.includes
方法。function autoComplete(Arr, Input) {
return Arr.filter(e =>e.toLowerCase().includes(Input.toLowerCase()));
}
function autoComplete(Arr, Input) { return Arr.filter(e=>e.toLowerCase().indexOf(Input.toLowerCase()) !== -1); }
- ronaldtgi我之前研究过这个问题,我的解决方案最初类似于这里的ES6解决方案,就像这样:
return this.data.filter((option) => {
return option.first_name
.toString()
.toLowerCase()
.indexOf(this.searchTerms.toLowerCase()) >= 0
})
this.data
:[
{ first_name: 'Bob', },
{ first_name: 'Sally', },
]
您可以看到,它基于this.searchTerms
进行过滤,同时将搜索词和option.first_name
转换为小写字母,但是它太过死板,无法搜索option.user.first_name
。我的最初尝试是传递要过滤的字段,例如:
this.field = 'user.first_name';
this.field.split('。')
的内容并动态生成过滤函数。
相反,我想起了一个我以前用过的叫做fuse.js
的旧库,它很好地工作,因为它不仅处理了我刚才称之为this.field
的任意嵌套情况,而且还根据定义的阈值处理模糊匹配。
在这里查看:https://fusejs.io/
[编辑说明]:我意识到这个问题正在寻找没有外部库,但我想保留这篇文章,因为它提供了相邻的价值。 这不是“解决方案”。
以下是我当前的使用方式:
import Fuse from 'fuse.js';
const options = {
threshold: 0.3,
minMatchCharLength: 2,
keys: [this.field],
};
const fuse = new Fuse(this.data, options);
this.filteredData = fuse.search(this.searchTerms);
new Fuse()
对象来进行过滤。
keys: [this.field]
部分很重要,因为这是你传递要搜索的键的位置,你可以传递一个数组。例如,你可以通过keys: ['user.first_name', 'user.friends.first_name']
来过滤this.data
。
我目前在Vue JS中使用它,所以我将上面的逻辑放在实例watch
函数中,因此每次this.searchTerms
更改时,该逻辑都会运行并更新this.filteredData
,然后将其放入我的自动完成组件的下拉列表中。
还有,很抱歉我刚才才意识到这个问题特别说明了不使用外部库,但我仍然会发布这篇文章,因为每次我在Vue JS或React JS中制作ES6自动完成时都会遇到这个问题。我认为严格或宽松模糊匹配非常有价值,并支持任意嵌套数据。根据Webpack包分析器,fuse.js
经过gzip压缩后只有4.1kb,因此它非常小,而且可以支持“所有”客户端过滤需求。
option.first_name
以类似option[this.field]
的方式来变量化搜索字段(即:如果您的对象始终是平面的),则它可以正常工作。const radicalFilter = ({ collection, field, searchTerms }) => {
return collection.filter((option) => {
return option[field]
.toString()
.toLowerCase()
.indexOf(searchTerms.toLowerCase()) >= 0
})
}
radicalFilter({
collection: [{ first_name: 'Bob' }, { first_name: 'Sally' }],
field: 'first_name',
searchTerms: 'bob',
})
根据我过去几年的经验,上面的示例非常高效。我在一个react-table
组件中用它来过滤10000条记录,它毫不费力。它不会创建任何额外的中间数据结构。它只是使用Array.prototype.filter()
对您的数组进行筛选,并返回匹配项的新数组。
我曾经通过向服务器发送JSON请求,并使用Python代码进行自动完成来实现这一点。虽然速度有点慢,但它避免了传输大量的数据。