如何使数据列表仅从头开始匹配结果

A V*_*yom 8 html javascript jquery

我想在 html 中制作数据列表,这里是示例

<h1>Datalist Demo</h1>
<label for="default">Pick a programming language</label>
<input type="text" id="default" list="languages">
<datalist id="languages">
    <option value="HTML">
    <option value="CSS">
    <option value="JavaScript">
    <option value="Java">
    <option value="Ruby And Go">
    <option value="PHP And HTML">
    <option value="Go">
    <option value="Erlang">
    <option value="Python And C++">
    <option value="C">
    <option value="C#">
    <option value="C++">
</datalist>
Run Code Online (Sandbox Code Playgroud)

但当我搜索“go”时,它显示了 2 个结果

  • Ruby And Go
  • Go

当我搜索“go”时的结果

我希望它只显示与输入文本开头匹配的术语,而不是从内部显示。
就像当我搜索“go”时,只应显示一个结果

  • Go

我必须对 MySQL 中存储的 5000 多条记录实施此操作。

Rom*_*din 4

对于这种情况有一个非常合理的解决方案:保留一个空的数据列表内部 html(如果为空,它将在焦点事件上填充)并使用 Javascript 在每个输入事件上动态填充它。在 JS 中,最好按字母顺序对选项数组进行排序,以便在已经找到一些巧合并且没有进一步匹配时能够停止迭代。继续这个问题的例子:

const dlOptions = ["C", "C#", "C++", "CSS", "Erlang", "Go", "HTML", "Java",
"JavaScript", "PHP And HTML", "Python And C++", "Ruby And Go"].map(o => {
    return [`<option value="${o}"></option>`, o.toLowerCase()];
});

function completeDataList(e) {
    const fill = val => document.getElementById('languages').innerHTML = val;
    if(!e.target.value) {
        fill(dlOptions.reduce((sum, [html]) => sum + html, ''));
    } else if(!(e instanceof InputEvent)) { // OR: else if(!e.inputType)
        e.target.blur();
    } else {
        const inputValue = e.target.value.toLowerCase();
        let result = '';
        for (const [html, valuePattern] of dlOptions) {
            if (!valuePattern.indexOf(inputValue)) {
                result += html;
            } else if (result) {
                break;
            }
        }
        fill(result);
    }
}

function fillDataListIfEmpty() {
    if(!document.getElementById('languages').innerHTML) {
        completeDataList({ target: {} });
    }
}
Run Code Online (Sandbox Code Playgroud)
<h1>Datalist Demo</h1>
<label for="default">Pick a programming language</label>
<input type="text" id="default" list="languages" oninput="completeDataList(event)" onfocus="fillDataListIfEmpty()">
<datalist id="languages"></datalist>
Run Code Online (Sandbox Code Playgroud)

PS 在桌面和移动设备上都像一个魅力(我在我的项目中使用这种方法,在大约 80 个选项的输入上生成数据列表)。然而,正如上面已经提到的,对于大量的选项,采用带有数据库查询的服务器解决方案更为合理。

UPD:使用这种方法时,应该注意的是,选择 datalist 选项也会触发输入事件(或者更准确地说,只是 Event 的实例,而不是 InputEvent 的实例),并且,为了良好的用户体验,应该考虑在内(否则选择选项后会再次错误地弹出datalist选项);keyup 事件也有类似的情况。我刚刚更新了代码。

UPD2:completeDataList我根据@heretic-monkey的建议编辑了该函数(详细信息请参阅本文下的评论)。此外,为了提高性能,选项值数组被转换为另一个静态搜索和 html 模式数组,并初始化为全局变量(以便在每个输入事件上使用这些模式,而不是在每个事件上多次重建它们) ),这在有大量选项和/或频繁调用函数的情况下至关重要。