如何检测用户何时从数据列表中选择了一个选项?

时间:2019-06-11 01:26:24

标签: javascript html

我希望能够检测到用户何时从链接到数据列表的input元素的下拉框中选择了一个选项,以便我可以使用该操作来触发另一个操作。

由于某种原因,单击数据列表下拉框不会触发click事件。因此使用它完全是不可能的。

使用change事件不起作用有两个原因。 Chrome的change事件非常好,当有人选择一个选项时,它将触发,但是,在Firefox中,直到input失去焦点后才会触发该事件。您可能认为您至少可以将change事件用于Chrome浏览器,但是可惜还有另一个主要问题-如果您输入所选内容的全文,然后单击一个选项,则为change事件永远不会被解雇,因为什么都没有改变:(

最后,我们得出一个非常丑陋但看似唯一的选择:将input元素的当前值与一个input事件的数据列表中的选项进行比较。这有很多问题。

  1. 如果一个选项是另一个选项的前缀(例如foofoobar),则不起作用。如果用户在选择foo之前键入foobar,则该代码将过早运行。
  2. 假设您的所有选项都不是彼此的前缀,那么如果用户在数据列表中键入内容的整个文本,而不是等待他们选择它们,则您的代码仍将运行。
  3. 每次您都要遍历数据列表中的每个选项 输入一个字符。

您可以尝试使用setTimeout来缓解这些问题,以检测某人何时停止键入,但这仍然无法实现所需的行为。

我不敢相信没有一个简单的事件可以解决这个问题,但是我知道必须必须

1 个答案:

答案 0 :(得分:0)

确实,有一种方法!我们的英雄是Invisible Separator(U + 2063)。它是一个字符,不会对字符串增加任何可见效果,它仅存在。复制并粘贴此f⁣oo并检查其长度。您会看到它等于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&#8291;</option>
    <option>bar&#8291;</option>
    <option>foobar&#8291;</option>
</datalist>
<div></div>