这是我的密码

import React, { useState, useRef } from "react";

const alphabet = ["A", "B", "C", "D", "E"];

export default function App() {
  const [selected, setSelected] = useState<number | null>(null);
  const selectedRef = useRef<HTMLDivElement>(null);

  const selectLetter = (i: number) => {
    if (selected === i) {
      setSelected(null);
    } else {
      setSelected(i);
    }
  };

  const navigate = (
    event: React.KeyboardEvent<HTMLDivElement>,
    letter: string,
    i: number
  ) => {
    if (event.key === "Enter") {
      if (i === selected) {
        setSelected(null);
      } else {
        setSelected(i);
      }
    }
  };

  return (
    <div
      tabIndex={-1}
      style={{
        display: "flex",
        gap: "5px",
        flexWrap: "wrap"
      }}
    >
      {alphabet.map((letter: string, i: number) => (
        <div
          ref={selected === i ? selectedRef : null}
          onClick={() => selectLetter(i)}
          onKeyDown={(event) => navigate(event, letter, i)}
          tabIndex={selected === i ? 0 : -1}
          style={{
            border: "1px solid blue",
            padding: "30px",
            backgroundColor: i === selected ? "blue" : "white",
            color: i === selected ? "white" : "black",
            fontWeight: "bolder",
            cursor: "pointer"
          }}
        >
          {letter}
        </div>
      ))}
    </div>
  );
}

我有字母"A"、"B"、"C"、"D"、"E".如果我单击它们,它们就会突出显示.一次只能 Select 一个字母,如果再次单击,则可以取消 Select .那部分很好用.

我遇到的问题是如何将键盘集成到工作中.

我也希望能够使用我的键盘,做同样的事情,但用键盘代替.让我们假设默认情况下tabIndex位于"A"上.如果我按enter键,它将突出显示"A"

enter image description here

如果我再次按enter键(取消 Select "A")

enter image description here

我还应该能够使用箭头键来移动tabIndex,例如,如果我使用右键,那么它将集中在"B"上.然后当我按enter键时,B应该高亮显示

enter image description here

我应该能够自由地用键盘导航A、B、C、D、E.

我正在mozilla上读tabindex的文章,我就是想不出来.我有点让enter工作,但按下一次后,我不确定如何让tabindex移动.

我的playground :https://codesandbox.io/s/clever-aryabhata-vxoi90?file=/src/App.tsx:0-1358

推荐答案

首先,您希望所有元素的tabIndex都是0,这样您就可以使用Tab键按顺序浏览它们.这是tabIndex属性的唯一用途.

然后,要通过箭头键导航,您可以判断ArrowLeft/ArrowRight event.key,然后.focus()上一个/下一个元素:

if (event.key === "ArrowLeft") {
  document.querySelectorAll("#root div div")[i-1]?.focus();
}
if (event.key === "ArrowRight") {
  document.querySelectorAll("#root div div")[i+1]?.focus();
}

这是您的更新代码Sandbox :https://codesandbox.io/s/empty-tdd-8g3prn?file=/src/App.tsx

Javascript相关问答推荐

在JS中获取名字和姓氏的首字母

获取加载失败:获取[.]添加时try 将文档添加到Firerestore,Nuxt 3

如何在JavaScript中在文本内容中添加新行

防止用户在selectizeInput中取消 Select 选项

将自定义排序应用于角形数字数组

如何修复(或忽略)HTML模板中的TypeScript错误?'

如何将Cookie从服务器发送到用户浏览器

如何在Vue 3中创建自定义 Select 组件,并将选项作为HTML而不是props 传递?

当我在Reaction中创建一个输入列表时,我的输入行为异常

Puppeteer上每页的useProxy返回的不是函数/构造函数

无法避免UV:flat的插值:非法使用保留字"

基于产品ID更新条带产品图像的JavaScript命中错误

使用Reaction窗体挂钩注册日历组件

postman 预请求中的hmac/sha256内标识-从js示例转换

顶点图使用组标签更新列之间的条宽

固定动态、self 调整的优先级队列

从异步操作返回对象

JQuery使用选项填充HTMLSELECT并设置默认结果,默认结果显示为空

相对于具有选定类的不同SVG组放置自定义工具提示

在Reaction Native中,ScrolltoIndex在结束时不一致地返回到索引0