通过按下和向上键在 keydown 事件中遍历 <div> 列表

Iterating through list of <div> on keydown event by pressing down and up key

此函数通过按下和向上键循环访问 <div> 的 keydown 事件列表。同样,当按下回车键时,<div> 文本内容被插入到 <input> 字段中。我想知道我做的功能的逻辑是否正确,或者事情可以做不同的事情。另外我想知道这个功能能不能缩短

const inputField = document.querySelector("input");

inputField.addEventListener("keydown", selectElement);

function selectElement(e) {
  const elements = document.querySelectorAll(".element");
  const len = elements.length - 1;

  if (e.keyCode == '40') {
    for (let i = 0; i <= len; i++) {
      if (elements[i].classList.contains("hover") && i != len) {
        elements[i].classList.remove("hover");
      } else if (elements[i].dataset.read !== "true") {
        elements[i].classList.add("hover");
        elements[i].dataset.read = true;
        break;
      }
    }
  }

  if (e.keyCode == '38') {
    for (let i = len; i >= 0; i--) {
      if (elements[i].classList.contains("hover") && i != 0) {
        elements[i].classList.remove("hover");
        elements[i].dataset.read = false;
      } else if (elements[i].dataset.read !== "false") {
        elements[i].classList.add("hover");
        break;
      }
    }
  }

  if (e.keyCode == '13') {
    for (let i = 0; i <= len; i++) {
      if (elements[i].classList.contains("hover")) {
        inputField.value = elements[i].textContent;
      }
    }
  }
}
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  font-family: Verdana, Geneva, Tahoma, sans-serif;
}

.container {
  display: inline-block;
  padding: 10px;
  background-color: #eee;
  border: 1px solid #ddd;
}

input {
  width: 200px;
  margin: 5px;
  padding: 5px;
  border: 1px solid #ddd;
}

.element {
  width: 200px;
  margin: 5px;
  padding: 10px;
  text-align: center;
  background-color: #fff;
  border: 1px solid #ddd;
}

.hover {
  background-color: #c1dff3;
}
<div class="container">
  <input type="text">
  <div class="element">Uno</div>
  <div class="element">Dos</div>
  <div class="element">Tres</div>
  <div class="element">Cuatro</div>
  <div class="element">Cinco</div>
</div>

我创建了一些小函数并稍微更改了逻辑。您可以查看此解决方案以获得一些见解。

const inputField = document.querySelector("#input");
const elements = document.querySelectorAll(".element");
inputField.focus();

let [activeIndex, length] = [-1, elements.length];

inputField.addEventListener("keydown", handleKeyDown);


function handleKeyDown(e) {
  const {key} = e;

  if(key === "ArrowDown") moveDown(e);
  if(key === "ArrowUp") moveUp(e);
  if(key === 'Enter') insertText(e);
}

function moveDown(e) {
  activeIndex = (activeIndex+1) % length;
  navigateThroughElement(activeIndex);
}

function moveUp(e) {
  if(activeIndex === -1) activeIndex = 0;
  activeIndex = (length + (activeIndex-1)) % length;
  navigateThroughElement(activeIndex);
}

function navigateThroughElement(index) {
  elements.forEach(el => {
    if(el.classList.contains('hover')) el.classList.remove('hover');
  })
  elements[index].classList.add('hover');
}

function insertText(e) {
  if(activeIndex >= 0) {
    e.target.value = elements[activeIndex].innerText;
  }
}
html {
  box-sizing: border-box;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body {
  font-family: Verdana, Geneva, Tahoma, sans-serif;
}

.container {
  display: inline-block;
  padding: 10px;
  background-color: #eee;
  border: 1px solid #ddd;
}

input {
  width: 200px;
  margin: 5px;
  padding: 5px;
  border: 1px solid #ddd;
}

.element {
  width: 200px;
  margin: 5px;
  padding: 10px;
  text-align: center;
  background-color: #fff;
  border: 1px solid #ddd;
}

.hover {
  background-color: #c1dff3;
}
<div class="container">
  <input type="text" id="input" placeholder="press up/down..." autocomplete="off">
  <div class="element">Uno</div>
  <div class="element">Dos</div>
  <div class="element">Tres</div>
  <div class="element">Cuatro</div>
  <div class="element">Cinco</div>
</div>

我整理了代码如下。 html:

<div>
  <div>
    <input type="text">
  </div>
  
  <div class="container">  
    <div class="element">Uno</div>
    <div class="element">Dos</div>
    <div class="element">Tres</div>
    <div class="element">Cuatro</div>
    <div class="element">Cinco</div>
  </div>
</div>

Javascript:

const inputField = document.querySelector("input");

inputField.addEventListener("keydown", selectElement);
window.curIndex = -1;

function selectElement(e) {
  var totalItems = document.querySelectorAll('.element').length;
  var selected = document.querySelector('.element.hover');
  
  // console.log(e.keyCode);
    
  if(e.keyCode === 13 && selected){
    inputField.value = selected.textContent;
  }
  else {
    console.log(window.curIndex);
    if(e.keyCode === 40){
      window.curIndex = (window.curIndex + 1) % totalItems;
      
    }
    else if(e.keyCode === 38){
      window.curIndex = window.curIndex <= 0? totalItems - 1: window.curIndex - 1;
    }
    
    console.log(window.curIndex);
    
    if(selected){
        selected.classList.remove('hover');
    }
    
    var selector = '.container .element:nth-child(' + (window.curIndex + 1) + ')';
    console.log(selector);
    selected = document.querySelector(selector);
    if(selected){
      console.log('Adding hover');
        selected.classList.add('hover');
    }
  }
  
}

Check the fiddle