首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用arrowKeys在元素之间导航?

如何使用arrowKeys在元素之间导航?
EN

Stack Overflow用户
提问于 2021-08-20 10:23:39
回答 1查看 60关注 0票数 0

这不是重复的问题。我已经检查了现有的答案,并应用了相同的解决方案,但它并不完全有效。

我有一个卡列表,并设置了addEventListener来跟踪ArrowRight和ArrowLeft。我不太确定如何才能让它聚焦并使用箭头键在卡片中移动。

我尝试了以下操作,但得到了一个错误".card:focus".next is not a function

代码语言:javascript
运行
复制
  useEffect(() => {
    document.addEventListener("keydown", (e) => {
      if (e.key === "ArrowRight") {
        ".card:focus".next().focus();
      }
      if (e.key === "ArrowLeft") {
        ".card:focus".prev().focus();
      }
    });
  });

这是DOM的样子:

父组件:

代码语言:javascript
运行
复制
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>
  );
}

子组件:

代码语言:javascript
运行
复制
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);
EN

Stack Overflow用户

发布于 2021-08-20 10:58:38

每个事件都有一个target property。Event接口的target属性是对事件调度到的对象的引用。

如果节点都在同一级别上,就像在屏幕截图上一样,您可以使用:

代码语言:javascript
运行
复制
// 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(),并添加一个“活动”的类或属性到当前查看的卡片,选择左或右。

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68860736

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档