我希望能够检测到用户何时从链接到数据列表的input
元素的下拉框中选择了一个选项,以便我可以使用该操作来触发另一个操作。
由于某种原因,单击数据列表下拉框不会不触发click
事件。因此使用它完全是不可能的。
使用change
事件不起作用有两个原因。 Chrome的change
事件非常好,当有人选择一个选项时,它将触发,但是,在Firefox中,直到input
失去焦点后才会触发该事件。您可能认为您至少可以将change
事件用于Chrome浏览器,但是可惜还有另一个主要问题-如果您输入所选内容的全文,然后单击一个选项,则为change事件永远不会被解雇,因为什么都没有改变:(
最后,我们得出一个非常丑陋但看似唯一的选择:将input
元素的当前值与一个input
事件的数据列表中的选项进行比较。这有很多问题。
foo
,foobar
),则不起作用。如果用户在选择foo
之前键入foobar
,则该代码将过早运行。 您可以尝试使用setTimeout
来缓解这些问题,以检测某人何时停止键入,但这仍然无法实现所需的行为。
我不敢相信没有一个简单的事件可以解决这个问题,但是我知道必须必须。
答案 0 :(得分:0)
确实,有一种方法!我们的英雄是Invisible Separator(U + 2063)。它是一个字符,不会对字符串增加任何可见效果,它仅存在。复制并粘贴此foo
并检查其长度。您会看到它等于4!
我们可以将此字符附加到数据列表中每个选项的末尾。然后,我们可以为input
事件设置侦听器,并检查input
元素的值是否以U + 2063结尾。如果是这样,您就知道用户已选择一个选项。然后,您应该更改input
元素的值以摆脱U + 2063(除非选择将触发总会重置该值的操作)。
这可以解决您所说的每个问题,因为用户实际上不能输入与数据列表中的内容相匹配的任何内容,因此必须选择一个选项来进行任何操作。
document.querySelector('input').addEventListener('input', function(){
if (this.value.slice(-1) == '\u2063') {
this.value = this.value.slice(0, -1);
let div = document.querySelector('div');
div.textContent = `you selected: ${this.value}`
div.classList.toggle('red'); //so you can see when this is called events even if the text doesn't change
}
});
body {
display: flex;
}
div {
margin-left: 1em;
}
.red {
color: red;
}
<input list='test'>
<datalist id='test'>
<option>foo⁣</option>
<option>bar⁣</option>
<option>foobar⁣</option>
</datalist>
<div></div>