以上所有的解决方案都有一个大问题。如果数据列表有(例如)“bob”和“bobby”的选项,一旦有人键入“bob”,他们的代码立即说这与单击“bob”相同......但如果他们试图输入“鲍比”?
为了获得更好的解决方案,我们需要更多信息。在输入字段上侦听“输入”事件时:
在基于 Chromium 的浏览器中,当您在输入字段中键入、删除、退格、剪切、粘贴等时,传递给处理程序的事件是InputEvent
,而当您从数据列表中选择一个选项时,事件只是具有Event
该属性的类型type
等于“输入”。(在自动填充期间也是如此,至少使用 BitWarden)。
所以你可以监听一个'input'事件并检查它是否是一个实例InputEvent
以确定它是否来自自动填充(我认为应该允许,因为大多数时候自动填充不会填充这些类型的字段,如果他们这样做,这通常是一个合法的选择)/数据列表选择。
但在 Firefox 中,情况有所不同。它仍然提供一个InputEvent
,但它有一个inputType
值为“insertReplacementText”的属性,我们也可以使用它。自动填充功能与 Chromium 浏览器相同。
所以这里有一个更好的解决方案:
$('#yourInput').on('input', function(){
if (
!(e instanceof InputEvent) ||
e.inputType === 'insertReplacementText')
) {
// determine if the value is in the datalist. If so, someone selected a value in the list!
}
});
我希望浏览器具有相同的实现,具有数据列表选择独有的事件类型/属性,但它们没有,所以这是我所拥有的最好的。我还没有在 Safari 上测试过这个(我现在没有访问权限或时间)所以你可能应该看看它,看看它是否相同或有其他显着差异。