【问题标题】:Is there a way using JavaScript to simulate a certain key keypress when pressing another key?有没有办法在按下另一个键时使用 JavaScript 来模拟某个键的按键?
【发布时间】:2020-10-30 09:19:04
【问题描述】:

就像按“a”键并输入“b”。似乎有很多与此类似的老问题,但答案似乎不起作用。不知道是因为 KeyboardEvent.initKeyEvent() 被弃用还是我的代码有缺陷,但我无法正确处理。

这是我尝试过的一些事情的示例:

document.addEventListener("keydown", evt => {
  evt.target.dispatchEvent(new KeyboardEvent('keydown', {"keyCode": 9, "which": 9}))
})

【问题讨论】:

    标签: javascript keyboard event-handling dom-events keydown


    【解决方案1】:

    新答案:

    const data = [
      "apple",
      "banana",
      "pear",
      "orange",
      "lemon",
      "lime",
      "grape",
      "cherry",
      "peach",
      "plum",
      "grapefruit",
      "watermelon",
      "kiwi"
    ]
    
    let suggestions = [];
    const container = document.getElementById("data");
    let index = 0;
    
    function handleChange(e) {
      const value = e.target.value;
      container.innerHTML = "";
      index = 0 ;
      suggestions = value ? data.filter(ele => ele.toLowerCase().includes(value)) : [];
     
      suggestions.forEach(ele => {
        const suggestion = document.createElement("div");
        suggestion.textContent = ele;
        container.append(suggestion);
      })
    }
    
    
    
    function handleKeydown(e) {
      if (e.keyCode === 9 && suggestions.length) {
        e.preventDefault();
        e.target.value = suggestions[index];
        index === suggestions.length - 1 ? index = 0 : index += 1;
      } else if (e.keyCode === 13) {
        container.innerHTML = ""
        index = 0;
        suggestions = [];
      }
    
    }
    <div> Type A Fruit </div>
    <input type="text" onkeydown="handleKeydown(event)" oninput="handleChange(event)" />
    <div id="data"> </div>

    旧答案:

    似乎不存在人工打开选择下拉菜单的方法;这是我能想到的最好的实现。

    let selected = false;
    
    function handleSelect(e) {
      if (e.keyCode === 9 && !selected) {
        e.preventDefault()
        const options = Array.from(e.target.children);
        if (!e.target.classList.contains('open')) {
          e.target.setAttribute('size', e.target.options.length)
          e.target.classList.toggle('open')
        } else {
          const index = options.findIndex(option => !!option.selected)
          if (options[index + 1]) {
            options[index + 1].selected = true;
          } else {
            options[0].selected = true;
          }
        }
      }
      if (e.keyCode === 13) {
        e.preventDefault();
    
        if (e.target.classList.contains('open')) {
          e.target.classList.toggle('open')
          e.target.setAttribute('size', "initial")
          selected = true;
        }
    
      }
    
     if (e.keyCode === 38 || e.keyCode === 40) {
       if (!e.target.classList.contains('open')) e.preventDefault();
     }
    }
    
    function handleBlur() {
      selected = false;
    }
    
    function handleClick(e) {
      Array.from(e.target.children)[1].focus();
    }
    .container {
      display: flex;
    }
    
    label {
      width: 100px;
      pointer-events: none;
    }
    
    select {
      pointer-events: none;
    }
    
    .open {
      position: absolute;
      left: 110px;
    }
    <div> click and hit tab </div>
    
    <div class="container" onclick="handleClick(event)">
      <label for="cars">Choose a car:</label>
    
      <select onkeydown="handleSelect(event)" onclick="handleClick(event)" onblur="handleBlur()" name="cars" id="cars">
        <option value="volvo">Volvo</option>
        <option value="saab">Saab</option>
        <option value="mercedes">Mercedes</option>
        <option value="audi">Audi</option>
      </select>
    </div>

    【讨论】:

    • 好的,但是如果我想在另一个键上设置“tab”键操作?
    • 我有一个text input 和一个datalist。用户开始输入 => 出现一个下拉列表,其中包含来自 datalist 的拟合 options。现在,当我在输入中获得焦点时导航选项,我不能使用tabshift+tab:它会将焦点从输入更改为下一个或上一个 html 流元素,我必须使用arrow downarrow up 键,这还不够合适。所以,在某些情况下,我想将tab的默认动作改为arrow down动作。
    • 我基本上希望输入/选项行为类似于您在浏览器地址搜索栏中的行为:您可以输入,您可以通过选项卡从下拉列表中进行选择,如果只有一个合适的下拉菜单左侧的选项,您只需按 Enter 即可自动完成。
    • 知道了;这应该以两种不同的方式可行,只是想看看更简单的方法是否有效。当我发现时会更新。
    • 感谢您对此事的奉献。如果有任何信息来源可以让我到达那里,我会很乐意调查它们:)
    猜你喜欢
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    • 2014-04-05
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 2010-12-19
    相关资源
    最近更新 更多