【问题标题】:Perform action when clicking HTML5 datalist option单击 HTML5 数据列表选项时执行操作
【发布时间】:2015-07-13 09:38:41
【问题描述】:

我正在使用<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();
}

但是,当我点击数据列表中的选择时,我无法让它执行操作,例如,如果我输入“Ref F”并且出现“Ref flowers”项目,如果我点击它我需要执行一个事件。

我该怎么做?

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

【问题讨论】:

  • 请提供相同的 js fiddle..我认为您在错误的时间附加事件..您需要在 DOM 中附加元素后绑定事件..
  • 您可以使用输入事件和setTimeout来避免每次触发输入:stackoverflow.com/a/69008887/557432

标签: javascript html dom-events html-datalist


【解决方案1】:

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

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;
      }
    }
  }
<input type='text' oninput='onInput()' id='input' list='dlist' />

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

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

不幸的是,无法判断用户是单击数据列表中的项目还是通过按 Tab 键选择它还是手动键入了整个字符串。

【讨论】:

  • 您还必须区分它和paste 事件......非常不同的路径可能不会到达相同的终点
  • 过滤器在 IE 中不起作用,我们还有其他解决方案吗?
  • 在 IE11 上,这与在 Firefox 中完全一样。您使用的是什么版本的 IE,究竟是什么不工作?
【解决方案2】:

由于缺乏可用于&lt;datalist&gt; 元素的事件,除了观看input 的事件(changeinput 等)之外,没有其他方法可以从建议中进行选择。也可以在这里查看我的答案:Determine if an element was selected from HTML 5 datalist by pressing enter key

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

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;
    }
  }
}
<input list="items" type="text" />
<datalist id="items">
  <option>item 1</option>
  <option>item 2</option>
</datalist>

【讨论】:

  • 感谢狙击手,但这不适用于我的解决方案,我认为是因为数据列表不断被重新填充和清空。
  • 完美运行,如果您使用
【解决方案3】:

使用keydown

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

键入和&lt;datalist&gt; 点击都会触发输入的keydown 侦听器,但只有键盘事件具有键属性。因此,如果触发 keydown 时没有 key 属性,您就知道这是从列表中点击

演示:

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 侦听器中切换的额外跟踪变量来添加。)

【讨论】:

  • 太棒了!这是非常聪明的。我试图将鼠标和按键事件都连接到输入,但很奇怪的是,尽管单击了下拉列表中的选项,但它仍会引发按键事件。这似乎是区分两者的唯一方法。
  • 很好的解决方案。不幸的是,Safari(15.1 版)在选择option 中的datalist 时不会触发keydown 事件,因此eventSource 不会得到更新并保持在最后一个状态。
【解决方案4】:

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;
             }
        }
    }

【讨论】:

    【解决方案5】:

    Shob 的答案是唯一可以检测何时单击选项以及 not 触发中间书面文本是否与选项匹配的答案(例如:如果有人键入“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>

    【讨论】:

      【解决方案6】:
      <input type="text" id="buscar" list="lalista"/>
      <datalist id="lalista">
        <option value="valor1">texto1</option>
        <option value="valor2">texto2</option>
        <option value="valor3">texto3</option>  
      </datalist>
      //0 if event raised from datalist; 1 from keyboard
      let idTimeFuekey = 0;  
      buscar.oninput = function(){
          if(buscar.value && idTimeFuekey==0) {
              alert('Chévere! vino desde la lista')
          }
      };
      buscar.onkeydown = function(event){
          if(event.key){ //<-- for modern & non IE browser, more direct solution
              window.clearInterval(idTimeFuekey);
              idTimeFuekey = window.setInterval(function(){ //onkeydown --> idTimeFuekey++ (non 0)
                  window.clearInterval(idTimeFuekey);
                  idTimeFuekey = 0 //after 500ms onkeydown --> 0 (could work 500, 50, .. 1)
              }, 500) 
          }
      }
      

      【讨论】:

      • 对 Internet Explorer
      • 也许可以尝试在那里解释你的代码。
      【解决方案7】:

      好吧,至少在 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>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多