为什么箭头键导航在反转方向时返回错误的值



我正试图使用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>

相关内容

最新更新