Перебор списка <div> при нажатии клавиши нажатием клавиши вниз и вверх

Эта функция перебирает список <div> по событию нажатия клавиши, нажимая клавиши вниз и вверх. Также при нажатии клавиши ввода текстовое содержимое <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>
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
876
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я создал несколько небольших функций и немного изменил логику. Вы можете проверить это решение, чтобы получить некоторое представление.

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>

Привет Сифат, спасибо за ответ. Мне нравится твоя новая перспектива. Ваше решение намного лучше и продвинутее. Мне нравится, что когда он доходит до конца, он снова начинается с самого начала.

Oscar VA 12.12.2020 04:19

Я упорядочил код следующим образом. 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.info(e.keyCode);
    
  if (e.keyCode === 13 && selected){
    inputField.value = selected.textContent;
  }
  else {
    console.info(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.info(window.curIndex);
    
    if (selected){
        selected.classList.remove('hover');
    }
    
    var selector = '.container .element:nth-child(' + (window.curIndex + 1) + ')';
    console.info(selector);
    selected = document.querySelector(selector);
    if (selected){
      console.info('Adding hover');
        selected.classList.add('hover');
    }
  }
  
}

Проверьте скрипку

Привет dotcoder, спасибо также за ответ. Невероятно, как каждый человек понимает и решает одну и ту же проблему по-разному. Ваше решение тоже очень хорошее.

Oscar VA 12.12.2020 04:23

Другие вопросы по теме