单击HTML5 datalist选项时执行操作

时间:2015-05-04 04:39:34

标签: javascript html5 dom-events html-datalist

我正在使用<datalist>

<datalist id="items"></datalist>

使用AJAX填充列表

 function callServer (input) {
    xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function(){
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
            //return the JSON object
            console.log(xmlhttp.responseText);
            var arr = JSON.parse(xmlhttp.responseText);
            var parentDiv = document.getElementById('items');
            parentDiv.innerHTML = "";
            //fill the options in the document
            for(var x = 0; x < arr.length; x++) {
                var option = document.createElement('option');
                option.value = arr[x][0];
                option.innerHTML = arr[x][1];
                //add each autocomplete option to the 'list'
                option.addEventListener("click", function() {
                  console.log("Test");
                });
                parentDiv.appendChild(option);
            };

        }
    }
    xmlhttp.open("GET", "incl/search.php?value="+input.value, true);
    xmlhttp.send();
}

但是,当我点击数据列表中的选项时,我无法执行操作,例如,如果我输入&#34;参考F&#34;和项目&#34; Ref flowers&#34;如果我点击它,我需要执行一个事件。

我该怎么做?

option.addEventListener("click", function() {
option.addEventListener("onclick", function() {
option.addEventListener("change", function() {

6 个答案:

答案 0 :(得分:19)

很抱歉挖掘这个问题,但我遇到了类似的问题并找到了解决方案,这对您也有用。

&#13;
&#13;
function onInput() {
    var val = document.getElementById("input").value;
    var opts = document.getElementById('dlist').childNodes;
    for (var i = 0; i < opts.length; i++) {
      if (opts[i].value === val) {
        // An item was selected from the list!
        // yourCallbackHere()
        alert(opts[i].value);
        break;
      }
    }
  }
&#13;
<input type='text' oninput='onInput()' id='input' list='dlist' />

<datalist id='dlist'>
  <option value='Value1'>Text1</option>
  <option value='Value2'>Text2</option>
</datalist>
&#13;
&#13;
&#13;

该解决方案源自Stephan Mullers解决方案。它也应该与动态填充的数据列表一起使用。

不幸的是,没有办法判断用户是否点击了数据列表中的某个项目,或者是通过按Tab键选择了该项目,还是手动输入了整个字符串。

答案 1 :(得分:8)

由于<datalist>元素缺少可用的事件,除了观看input的事件(change,{{1}之外,无法从建议中进行选择等等)。另请参阅我的答案:Determine if an element was selected from HTML 5 datalist by pressing enter key

要检查是否从列表中选择了某个选项,您应该将每个更改与可用选项进行比较。这意味着当用户手动输入确切值时,事件也将触发,无法停止此操作。

input
document.querySelector('input[list="items"]').addEventListener('input', onInput);

function onInput(e) {
   var input = e.target,
       val = input.value;
       list = input.getAttribute('list'),
       options = document.getElementById(list).childNodes;

  for(var i = 0; i < options.length; i++) {
    if(options[i].innerText === val) {
      // An item was selected from the list!
      // yourCallbackHere()
      alert('item selected: ' + val);
      break;
    }
  }
}

答案 2 :(得分:1)

Shob 的答案是唯一一个可以检测选项何时被点击以及触发的,如果中间书面文本与选项匹配(例如:如果有人输入“Text1”以查看选项) “Text11”、“Text12”等,即使“Text1”在数据列表中也不会触发。

然而,最初的答案似乎不适用于较新版本的 Firefox,因为 keydown 事件不会在点击时触发,所以我对其进行了调整。

let keypress = false;
document.getElementById("dinput").addEventListener("keydown", (e) => {
    if(e.key) {
        keypress = true;
    }
});
document.getElementById("dinput").addEventListener('input', (e) => {
    let value = e.target.value;
    if (keypress === false) {
        // Clicked on option!
        console.debug("Value: " + value);
    }
    keypress = false;
});
<input type="text" id="dinput" list="dlist" />

<datalist id="dlist">
  <option value="Value1">Text1</option>
  <option value="Value2">Text2</option>
</datalist>

答案 3 :(得分:0)

Datalist不支持点击监听器,OnInput非常昂贵,如果有任何变化,每次检查所有列表。

我所做的是使用:

document.querySelector('#inputName').addEventListener("focusout", onInput);

每次客户点击输入文字时都会触发FocusOut,而不是点击其他任何地方。如果他们点击了文本,那么点击其他地方我会假设他们放了他们想要的价值。

要检查值是否有效,请执行与输入相同的操作:

   function onInput(e) {
        var val = document.querySelector('#inputName').value;
        options = document.getElementById('datalist').childNodes;
        for(var i = 0; i < options.length; i++) {
             if(options[i].innerText === val) {
                  console.log(val);
                  break;
             }
        }
    }

答案 4 :(得分:0)

使用keydown

与其他答案相反,可以 检测是从列表中键入还是选择了一个选项。

键入和单击<datalist>都会触发输入的keydown侦听器,但是只有键盘事件才具有key属性。因此,如果触发了keydown没有密钥属性,那么您就会知道这是列表中的点击

演示:

const opts = document.getElementById('dlist').childNodes;
const dinput = document.getElementById('dinput');
let eventSource = null;
let value = '';

dinput.addEventListener('keydown', (e) => {
  eventSource = e.key ? 'input' : 'list';
});
dinput.addEventListener('input', (e) => {
  value = e.target.value;
  if (eventSource === 'list') {
    alert('CLICKED! ' + value);
  }
});
<input type="text" id="dinput" list="dlist" />

<datalist id="dlist">
  <option value="Value1">Text1</option>
  <option value="Value2">Text2</option>
</datalist>

请注意,如果单击的值已在框中,它不会提醒您,但这可能是合乎需要的。 (也可以使用额外的跟踪变量来添加此变量,该变量将在keydown侦听器中切换。)

答案 5 :(得分:0)

好吧,至少在 Firefox 中,onselect 事件适用于输入标签

<input type="text" id="dinput" list="dlist" onselect="alert(this.value)"/>

<datalist id="dlist">
  <option value="Value1">Text1</option>
  <option value="Value2">Text2</option>
</datalist>