这不是重复的问题。我已经检查了现有的答案,并应用了相同的解决方案,但它并不完全有效。
我有一个卡列表,并设置了addEventListener来跟踪ArrowRight和ArrowLeft。我不太确定如何才能让它聚焦并使用箭头键在卡片中移动。
我尝试了以下操作,但得到了一个错误".card:focus".next is not a function
useEffect(() => {
document.addEventListener("keydown", (e) => {
if (e.key === "ArrowRight") {
".card:focus".next().focus();
}
if (e.key === "ArrowLeft") {
".card:focus".prev().focus();
}
});
});这是DOM的样子:

父组件:
import React, { useEffect, useState } from "react";
import { getPokemons } from "../graphql/fetch/getPokemons.js";
import styled from "styled-components";
import "../components/pokemon-card";
const Cards = styled.div`
display: flex;
`;
export default function Pokemon() {
const [isLoading, setIsLoading] = useState(true);
const [pokemons, setPokemons] = useState([]);
useEffect(() => {
getPokemons().then((response) => {
console.log(response.data.pokemons);
setPokemons(response.data.pokemons);
setIsLoading(false);
});
}, []);
useEffect(() => {
document.addEventListener("keydown", (e) => {
if (e.key === "ArrowRight") {
".card:focus".next().focus();
}
if (e.key === "ArrowLeft") {
".card:focus".prev().focus();
}
});
});
if (isLoading) {
return <p>is loading</p>;
}
return (
<Cards>
{pokemons.map((pokemon) => (
<pokemon-card name={pokemon.name} image={pokemon.image}></pokemon-card>
))}
</Cards>
);
}子组件:
import { LitElement, html, css } from "lit-element";
class PokemonCard extends LitElement {
static styles = css`
.card {
background: white;
border-radius: 1rem;
padding: 2rem;
box-shadow: 4px 4px 12px 2px rgba(0, 0, 0, 0.75);
height: 500px;
transition: 0.2s;
}
.card:hover,
.card:focus-within {
transform: translateY(-5rem);
}
`;
static get properties() {
return {
name: { type: String },
image: { type: String },
};
}
render() {
const { name, image } = this;
return html`
<div class="card">
<p>${name}</p>
<img src=${image} />
</div>
`;
}
}
customElements.get("pokemon-card") ||
customElements.define("pokemon-card", PokemonCard);发布于 2021-08-20 10:58:38
每个事件都有一个target property。Event接口的target属性是对事件调度到的对象的引用。
如果节点都在同一级别上,就像在屏幕截图上一样,您可以使用:
// Using ElementChild and ElementSibling skips text-nodes
// if there is no need for skipping them, make use of nextChild,
// nextSibling and so on
// in case of right arrow:
if (e.target.classList.contains("card")) {
if (e.target.nextElementSibling) {
e.target.nextElementSibling.focus()
} else {
e.target.parentNode.firstElementChild.focus();
}
}
// in case of left arrow:
if (e.target.classList.contains("card")) {
if (e.target.previousElementSibling) {
e.target.previousElementSibling.focus()
} else {
e.target.parentNode.lastElementChild.focus();
}
}只需注意:
请记住,可以具有焦点的元素是有限的。它们必须是锚点(设置了href属性)、按钮、输入、文本区、select (未禁用)、contenteditable、iframe或要求设置tabindex-attribute。(另请参阅this answer)
如果你只是想滚动到一个元素,你可以利用element.scrollIntoView(),并添加一个“活动”的类或属性到当前查看的卡片,选择左或右。
https://stackoverflow.com/questions/68860736
复制相似问题