如何根据输入值可靠地计算数据列表中的匹配数?

How do I reliably count the number of matches in a Datalist based on Input value?

我有一个填充的 datalist 元素与一个 input 元素相关联,以在现代浏览器上启用本机自动完成功能:

HTML代码

<input type="search" id="search" list="autocomplete" />

<datalist id="autocomplete">
    <option value="c++" />
    <option value="javascript" />
    <option value="html" />
    <option value="php" />
</datalist>

使用JavaScript,什么是可靠根据[=的值计算匹配数的方法14=] 输入?我问这个的原因是因为处理自动完成是本机浏览器功能,我预计会有多种算法来选择供应商之间的匹配项。

我不需要复制或模仿每个浏览器的算法,我只需要找到一种方法来判断选择了多少个浏览器。

一个简单的 indexOf() 调用产生看似可靠的结果,但我找不到任何可以确保其准确的资源 - 此外,根据浏览器的不同,您可能会看到值之间的差异n_matches 和显示的实际选项数:

JavaScript

for (var i = 0; i < options.length; i++) {
    if (options[i].value.indexOf(search.value) !== -1)
        n_matches++;
}

Working demo on JSFiddle.

我知道你们中的大多数人可能会使用 jQuery 或其他库来完成此任务,但我宁愿坚持使用新发现的本机方法。

您当前的解决方案似乎给出了一些错误的结果。如果您输入字母 a,您的循环将显示 5 个结果,但将显示 0 个选项。 indexOf() 计算 javascript、java、visual basic、chapel 和 charm。

所以不再使用 indexOf(),改为使用 charAt(0)。使用 charAt() 我们将比较搜索输入的第一个字母和可能选项的第一个字母。

if (options[i].value.charAt(0) === this.value.charAt(0))

这可以让您准确可靠地计算将显示的选项数量。

这是您更新后的 fiddle

我在 Chrome 和 IE 中测试过。你得到相同的结果。


更新 - 发现错误

Search     Results    Options
a            0
h            1          html
j            2          javascript, java
javascript   2          javascript

所以我们可以看到最后的结果是不正确的。所以我们要使用你和我的原始解决方案。这将防止上面 table.

中的最终情况
if (options[i].value.charAt(0) === this.value.charAt(0) && options[i].value.indexOf(this.value) !== -1)

Updated solution

我知道这是一个旧的 post 但是,我对这两种解决方案都有疑问。上面的两种解决方案要么只在部分时间返回正确的数字,要么在缩小选项范围时一直返回 0。对我有用的解决方案实际上是在缩小结果范围时查看是否有任何选项包含搜索条件。

for(var i = 0; i < options.length; i++) {
    if (options[i].value.toLowerCase().includes(search.value.toLowerCase()))
        n_matches++;
}