javascript - 使用 Javascript 应用 KeyUp 和 KeyDown
问题描述
我是 JS 新手,需要您帮助解决这个问题。我需要使用 HTML、CSS 和 JS 应用 key-up 和 key-down。我有原始代码,我正在尝试修改它,以便可以使用向上键和向下键在面板中移动,但它似乎根本不起作用。这是我正在处理的部分的原始代码片段:
const P_CONTAINERS_LIST = "containersList";
const P_CONTAINER_EDIT = "containerEdit";
const P_CONTAINER_DELETE = "containerDelete";
Logic.registerPanel(P_CONTAINERS_EDIT, {
panelSelector: "#edit-containers-panel",
// This method is called when the object is registered.
initialize() {
Logic.addEnterHandler(document.querySelector("#exit-edit-mode-link"), () => {
Logic.showPanel(P_CONTAINERS_LIST);
});
},
// This method is called when the panel is shown.
prepare() {
const fragment = document.createDocumentFragment();
Logic.identities().forEach(identity => {
const tr = document.createElement("tr");
fragment.appendChild(tr);
tr.classList.add("container-panel-row");
tr.innerHTML = escaped`
<td class="userContext-wrapper">
<div class="userContext-icon-wrapper">
<div class="usercontext-icon"
data-identity-icon="${identity.icon}"
data-identity-color="${identity.color}">
</div>
</div>
<div class="container-name truncate-text"></div>
</td>
<td class="edit-container pop-button edit-container-icon">
<img
src="/img/container-edit.svg"
class="pop-button-image" />
</td>
<td class="remove-container pop-button delete-container-icon">
<img
class="pop-button-image"
src="/img/container-delete.svg"
/>
</td>`;
tr.querySelector(".container-name").textContent = identity.name;
tr.querySelector(".edit-container").setAttribute("title", `Edit ${identity.name} container`);
tr.querySelector(".remove-container").setAttribute("title", `Remove ${identity.name} container`);
Logic.addEnterHandler(tr, e => {
if (e.target.matches(".edit-container-icon") || e.target.parentNode.matches(".edit-container-icon")) {
Logic.showPanel(P_CONTAINER_EDIT, identity);
} else if (e.target.matches(".delete-container-icon") || e.target.parentNode.matches(".delete-container-icon")) {
Logic.showPanel(P_CONTAINER_DELETE, identity);
}
});
});
const list = document.querySelector("#edit-identities-list");
list.innerHTML = "";
list.appendChild(fragment);
return Promise.resolve(null);
},
});
<div class="scrollable panel-content" tabindex="-1">
<table class="unstriped">
<tbody id="edit-identities-list"></tbody>
</table>
</div>
我尝试在我的 JS 代码中插入以下部分,但问题仍然存在:
document.addEventListener("keydown", (e) => {
const selectables = [...document.querySelectorAll("[tabindex='0'], [tabindex='-1']")];
const element = document.activeElement;
const index = selectables.indexOf(element) || 0;
function next() {
const nextElement = selectables[index + 1];
if (nextElement) {
nextElement.focus();
}
}
function previous() {
const previousElement = selectables[index - 1];
if (previousElement) {
previousElement.focus();
}
}
switch (e.keyCode) {
case 40:
next();
break;
case 38:
previous();
break;
default:
if ((e.keyCode >= 49 && e.keyCode <= 57) &&
Logic._currentPanel === "containerEdit") {
const element = selectables[e.keyCode - 48];
if (element) {
element.click();
}
}
break;
}
});
解决方案
您的样本似乎很实用,所以我怀疑您的问题与这方面Logic._currentPanel
的内容和概念有关document.activeElement
。
对于超出索引或未知的selectables.indexOf(element)
结果-1
,element
不是null
或undefined
,所以const index = selectables.indexOf(element) || 0;
不会0
;
document.addEventListener("keydown", (e) => {
const selectables = [...document.querySelectorAll("[tabindex='0'], [tabindex='-1']")];
const element = document.activeElement;
const index = selectables.indexOf(element) || 0;
function next() {
const nextElement = selectables[index + 1];
if (nextElement) {
nextElement.focus();
}
}
function previous() {
const previousElement = selectables[index - 1];
if (previousElement) {
previousElement.focus();
}
}
switch (e.keyCode) {
case 40:
next();
break;
case 38:
previous();
break;
default:
if ((e.keyCode >= 49 && e.keyCode <= 57)) {
const element = selectables[e.keyCode - 48];
if (element) {
element.click();
}
}
break;
}
});
div {
display:block;
padding: 1in;
border:0.1em solid black;
}
div:focus {
box-shadow: 0px 0px 10px green;
}
<div tabindex="-1">
1
</div>
<div tabindex="-1">
2
</div>