19

我正在使用数据列表,需要检测用户何时从下拉列表中选择某些内容。有人问了一个类似的问题,但我需要它,以便仅当用户从数据列表中选择某些内容时才会触发事件。如果他们在输入中输入内容,那么我不希望事件触发。(请注意,在我链接的问题的已接受答案中,它们绑定了输入,这不是我想要的)。我试过(没有成功):

<datalist>
    <option>Option 1 Here</option> 
    <option>Option 2 Here</option>
</datalist>


$(document).on('change', 'datalist', function(){
   alert('hi');
});

编辑:这个问题与建议的问题不同,因为它是一个完全不同的问题。

4

8 回答 8

9

您可以在更改时手动检查它。但是你需要检查datalist输入的变化。

$(document).on('change', 'input', function(){
    var options = $('datalist')[0].options;
    var val = $(this).val();
    for (var i=0;i<options.length;i++){
       if (options[i].value === val) {
          alert(val);
          break;
       }
    }
});

小提琴

于 2014-05-14T06:59:47.683 回答
5

在具有 InputEvent 上的inputType属性的浏览器中,您可以使用它来过滤掉任何不需要的 onInput 事件。这是 Firefox 81 上的“insertReplacementText”,Chrome/Edge 86 上为 null。如果您需要支持 IE11,则需要验证该值是否有效。

document.getElementById("browser")
  .addEventListener("input", function(event){
        if(event.inputType == "insertReplacementText" || event.inputType == null) {
          document.getElementById("output").textContent =  event.target.value;
          event.target.value = "";
    }
})
<label for="browser">Choose your browser from the list:</label>
<input list="browsers" name="browser" id="browser">
<datalist id="browsers">
  <option value="Edge">
  <option value="Firefox">
  <option value="Chrome">
  <option value="Opera">
  <option value="Safari">
</datalist>
<div id="output">
</div>

于 2020-10-16T16:22:16.040 回答
4

以上所有的解决方案都有一个大问题。如果数据列表有(例如)“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 上测试过这个(我现在没有访问权限或时间)所以你可能应该看看它,看看它是否相同或有其他显着差异。

于 2021-06-22T16:58:17.490 回答
3

请寻找您的解决方案,这很好。寻找Demo

$(document).on('change', 'input', function(){
    var optionslist = $('datalist')[0].options;
    var value = $(this).val();
    for (var x=0;x<optionslist.length;x++){
       if (optionslist[x].value === value) {
          //Alert here value
          alert(value);
          break;
       }
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input list="data">
<datalist id="data">
    <option value='1'>Option 1 Here</option> 
    <option value='2'>Option 2 Here</option>
</datalist>

于 2018-09-24T08:51:39.817 回答
3

优化方案

$("input").on('input', function () {
    var inputValue = this.value;
    if($('datalist').find('option').filter(function(){
        return this.value == inputValue;        
    }).length) {
        //your code as per need
        alert(this.value);
    }
});
于 2018-05-17T10:21:18.073 回答
0

更多优化

$("input").on('input', function () {
  if($('datalist').find('option[value="'+this.value+'"]')){
    //your code as per need
    alert(this.value);
  }
});
于 2019-09-04T07:49:39.020 回答
0
jQuery('input').on('input', function () {
  if($('datalist[id="' + jQuery(this).attr('list') + '"]').find('option[value="'+this.value+'"]')){
    //your code as per need
    alert(this.value);
  }
});

所以它会找到与输入关联的数据列表

于 2022-02-27T20:32:45.080 回答
0

这可能只是 Chrome,在其他任何地方都未经测试!,但我看到change选择一个选项时触发了一个事件。通常change仅在字段失去焦点时发生在文本字段中。如果事件是正常的非数据列表更改,change则事件在事件之前触发,因此我们必须同时检查两者:我们正在寻找不紧跟a 的 a :blurchangeblur

var timer;
el.addEventListener('change', function(e) {
    timer = setTimeout(function() {
        el.dispatchEvent(new CustomEvent('datalistchange'));
    }, 1);
});
el.addEventListener('blur', function(e) {
    clearTimeout(timer);
});

datalistchange然后你可以像往常一样监听自定义事件。或者您可以只放置您的特定逻辑而不是dispatchEvent.

jsFiddle在这里

于 2020-09-23T15:01:57.267 回答