从datalist中选择项目时触发事件,而不是在键入时触发事件

时间:2017-07-25 21:05:29

标签: jquery html5 html-datalist

我有一个这样的表格:

<input list='data-list' id='list'>
<datalist id='data-list'>
  <option>first</option>
  <option>second</option>
</datalist>

用户可以从数据列表中选择一个项目 - 或者 - 可以输入自己的值。我通过对PHP脚本的JSON调用连接到数据库,以填写表单其余部分的其他信息。我想在用户在list-input中输入一个名字时触发(当内容模糊时)或者当用户点击datalist中的一个选项时触发。

使用$( ':input#list' ).on( 'change', function...当输入失去焦点时会触发该功能,但是当选择数据列表中的某个项时,它也会等待直到输入失去焦点,我希望事件直接触发远

使用$( ':input#list' ).on( 'input', function...点击数据列表中的项目会立即触发该功能,这就是我想要的,但键入也会触发事件,每次击键,都会向我的PHP脚本发送大量不需要的请求

我已尝试直接将事件绑定到datalist,但这并不起作用。

我希望在用户点击(或使用键盘选择)数据列表中的项目时或者当用户输入单词并移动到下一个输入时触发该功能。

2 个答案:

答案 0 :(得分:0)

我选择的解决方案是两个事件的组合......

我会跟踪变量window.latest_autofill_qeury,以防止连续两次加载相同的内容。我有以下onchange函数,当用户将焦点从输入中移出(标签输出或在其他地方点击)时会触发此操作

$( ':input#list' ).on( 'change', function(){
   var current = $( this ).val();
   if( window.latest_autofill_query != current )
      load_autofill();
} );

然后是另一个跟踪用户输入内容的函数,并检查输入的值是否在datalist中。如果是这样,我们假设用户想要的是什么,并查询下一个数据列表。当用户单击数据列表中的项目时,也会触发此操作,这将始终导致输入值出现在数据列表中,从而立即触发load_autofill:

$( ':input#list' ).on( 'input', function(){
   var current = $( this ).val();
   $( 'datalist#data-list option' ).each( function(){
      if( $( this ).text() == current ){
         load_autofill();
         return false;     //* break out of jQuery each loop
   } );
} );

load_autofill函数跟踪最后加载的内容以防止双重加载。我不知道这个load_autofill的详细信息,因为它非常适合应用程序,但框架是这样的:

function load_autofill(){
    var current = $( ':input#list' ).val();
    window.latest_autofill_query = current;

    //* ... perform loading of the next datalist
}

现在,只要用户从数据列表中选择了一个项目,就会加载下一个数据列表,但是只有当输入的文本出现在数据列表中时,才会在用户进行每次击键后立即加载。

答案 1 :(得分:-1)

您可以设置两个单独的事件侦听器。

一个人监听新输入并检查新输入是否与数据列表中的任何选项相对应。

当用户输入单词并继续进行下一个输入时,另一个会监听。

工作示例:

var myForm = document.getElementsByTagName('form')[0];
var myInput = myForm.getElementsByTagName('input')[0];
var myDataList = myForm.getElementsByTagName('datalist')[0];
var myOptions = myDataList.getElementsByTagName('option');

function listOptionSelected() {
    var myValue = myInput.value;
    for (var i = 0; i < myOptions.length; i++) {
        if (myOptions[i].value === myValue) {
            console.log('Option Selected: ' + myValue);
        }
    }
}

function typedOptionSelected() {
    var myValue = myInput.value;
    if (myValue !== '') {
        console.log('Option Selected: ' + myInput.value);
    }
}

myInput.addEventListener('input', listOptionSelected, false);
myInput.addEventListener('blur', typedOptionSelected, false);
input {
display: block;
margin: 0 0 12px 0;
}
<form action="#">
<input list='data-list' id='list'>
<datalist id='data-list'>
  <option>first</option>
  <option>second</option>
</datalist>

<input id="next-input" />
</form>