Эта функция перебирает список <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>
Я создал несколько небольших функций и немного изменил логику. Вы можете проверить это решение, чтобы получить некоторое представление.
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.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, спасибо также за ответ. Невероятно, как каждый человек понимает и решает одну и ту же проблему по-разному. Ваше решение тоже очень хорошее.
Привет Сифат, спасибо за ответ. Мне нравится твоя новая перспектива. Ваше решение намного лучше и продвинутее. Мне нравится, что когда он доходит до конца, он снова начинается с самого начала.