javascript - 为什么方向键导航在反转方向时会返回错误的值?
问题描述
我正在尝试使用 keydown 事件创建由箭头键控制的列表导航。选择按预期工作,直到用户反转方向。例如,如果用户在第 3 项上并点击向下箭头,则转到第 4 项。但是,如果用户然后按向上箭头,而不是返回第 3 项,则转到第 5 项。向上箭头的行为符合预期。只有在改变方向时,第一次按键才会产生不正确的结果。
谁能告诉我这是为什么?
function keyListener() {
"use strict";
let index = 1;
document
.querySelector(".select__element")
.addEventListener("keydown", (e) => {
let keyValue = e.key;
// ****************************** ARROW UP
if (keyValue === "ArrowUp") {
console.log("Arrow Up Pressed");
const selectItem = document.querySelectorAll(".select__item");
const length = selectItem.length - 1;
// dropdown the list
document
.querySelector(".select__list")
.classList.add("select__list--visible");
let indexPrev = index - 1;
if (indexPrev < 0) {
indexPrev = length;
}
let indexNext = index + 1;
if (indexNext > length) {
indexNext = 0;
}
// test the bounds
if (index < 0) {
index = length;
indexPrev = length - 1;
indexNext = 0;
}
if (index > length) {
index = 0;
indexPrev = index + 1;
indexNext = length;
}
console.log(
"Up Arrow: ",
indexPrev,
index,
indexNext,
"Values should decrease"
);
// select the item
selectItem[index].classList.add("select__item--selected");
selectItem[indexPrev].classList.remove("select__item--selected");
selectItem[indexNext].classList.remove("select__item--selected");
index--;
}
// ****************************** ARROW DOWN
if (keyValue === "ArrowDown") {
console.log("Arrow Down Pressed");
const selectItem = document.querySelectorAll(".select__item");
const length = selectItem.length - 1;
// dropdown the list
document
.querySelector(".select__list")
.classList.add("select__list--visible");
let indexPrev = index - 1;
if (indexPrev < 0) {
indexPrev = length;
}
let indexNext = index + 1;
if (indexNext > length) {
indexNext = 0;
}
// test the bounds
if (index < 0) {
index = length;
indexPrev = 0;
indexNext = length - 1;
}
if (index > length) {
index = 0;
indexPrev = length;
indexNext = index + 1;
}
console.log(
"Down Arrow: ",
indexPrev,
index,
indexNext,
"Values should increase"
);
//select the item
selectItem[index].classList.add("select__item--selected");
selectItem[indexPrev].classList.remove("select__item--selected");
selectItem[indexNext].classList.remove("select__item--selected");
index++;
}
});
}
keyListener();
.select__item--selected,
.select__item:hover {
background: #25A0DA;
color: #fff;
}
.select__root {
background-color: lightpink;
}
<div class="m-wrapper">
<div id="Select-Pages" class="select">
<div class="select__element" tabindex="0">
<div class="select__root">Select an item...</div>
<ul class="select__list">
<li class="select__item select__item--selected">Item-1</li>
<li class="select__item">Item-2</li>
<li class="select__item">Item-3</li>
<li class="select__item">Item-4</li>
<li class="select__item">Item-5</li>
<li class="select__item">Item-6</li>
</ul>
</div>
</div>
解决方案
修改类列表后,index
变量会递增和递减。因此,突出显示与所选索引不同步。我建议在类列表之前更新变量,如下所示。
此外,由于selectItem
数组索引从零开始,我建议定义index = 0
.
function keyListener() {
"use strict";
const selectItem = document.querySelectorAll(".select__item");
const length = selectItem.length;
let index = 0;
document
.querySelector(".select__element")
.addEventListener("keydown", (e) => {
let keyValue = e.key;
// store last index
let lastIndex = index;
// decrement / increment index
if (keyValue === "ArrowUp") {
index--;
}
if (keyValue === "ArrowDown") {
index++;
}
// keep index within range
index = (index + length) % length;
// deselect last item
selectItem[lastIndex].classList.remove("select__item--selected");
// select current item
selectItem[index].classList.add("select__item--selected");
});
}
keyListener();
.select__item--selected,
.select__item:hover {
background: #25A0DA;
color: #fff;
}
.select__root {
background-color: lightpink;
}
<div id="Select-Pages" class="select">
<div class="select__element" tabindex="0">
<div class="select__root">Select an item...</div>
<ul class="select__list">
<li class="select__item select__item--selected">Item-1</li>
<li class="select__item">Item-2</li>
<li class="select__item">Item-3</li>
<li class="select__item">Item-4</li>
<li class="select__item">Item-5</li>
<li class="select__item">Item-6</li>
</ul>
</div>
</div>
推荐阅读
- c++ - 在 MFC 中嵌入 Windows Media Player
- apify - 如何在 apify 中使用代理和基本爬虫
- python - 如何检查同一数据框列中的重复值并通过根据频率删除行来应用 if 条件?
- android - 在 Nest Hub 上显示数据:使用 Cast SDK 还是 Assistant SDK?
- discord.py - 打印错误代码不起作用(PyCharm,Python 3.8)
- java - BLE Android API - onCharacteristicChanged() 上的数据包丢失和数据频率下降并带有通知
- aws-cli - AWS CLI 不支持 MultiFactorAuthAge
- reactjs - 尝试设置输入属性时反应useRef返回未定义的错误
- javascript - Javascript - 将一些文本动态复制到剪贴板
- bash - 如何使 bash 仅在确切位置上完成,然后恢复正常