为什么方向键导航 returns 反向时值不对?
Why does arrow key navigation returns the wrong value when reversing direction?
我正在尝试使用 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
变量在 class 列表修改后递增和递减。结果,突出显示与所选索引不同步。我建议在 class 列表 之前更新变量 ,如下所示。
此外,由于 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>
我正在尝试使用 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
变量在 class 列表修改后递增和递减。结果,突出显示与所选索引不同步。我建议在 class 列表 之前更新变量 ,如下所示。
此外,由于 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>