You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何为列表元素监听keyPress事件?

解决列表元素键盘按键事件监听无效的问题

问题根源

  1. onKeyPress已废弃且兼容性受限:该事件在现代浏览器中对方向键、回车键等常用按键不会触发,且MDN已标记为废弃,推荐用onKeyDown或onKeyUp替代。
  2. 元素未获取焦点:即便设置了tabIndex={0},键盘事件仅在元素获得焦点时才会触发,需通过Tab键切换到目标元素后再测试。

修复方案

1. 替换事件类型为onKeyDown

将原onKeyPress替换为onKeyDown,并在封装的MotionLI组件中同步支持该属性传递。

2. 完善无障碍键盘交互

对于role="button"的元素,需支持回车键和空格键触发点击逻辑,这是无障碍访问的标准要求。

修改后的代码示例

父组件部分

<MotionUL variants={dropUlAnimVariant}>
  {category.map((item, i, arr) => {
    const handleKeyDown = (e) => {
      // 监听回车和空格键,模拟点击行为
      if (e.key === 'Enter' || e.key === ' ') {
        e.preventDefault(); // 阻止空格默认滚动行为
        setCurrentCatItem(item);
        dispatch({ type: 'select', payload: i });
        console.log(item); // 现在可正常输出
      }
      // 如需监听更多按键,可在此扩展判断,比如方向键
      // if (e.key === 'ArrowUp' || e.key === 'ArrowDown') { ... }
    };

    return (
      <MotionLI
        key={i}
        className={`cursor-pointer list-none ${
          i === state.selectIndex ? 'text-white' : 'text-gray-400'
        }  hover:text-white ${
          item === arr.slice(-1).join('') ? 'border-none' : 'border-b border-[#2d2d2d]'
        } py-2`}
        role="button"
        ariaPressed={i === state.selectIndex}
        tabIndex={0}
        onClick={() => {
          setCurrentCatItem(item);
          dispatch({ type: 'select', payload: i });
        }}
        onKeyDown={handleKeyDown} // 替换为onKeyDown事件
      >
        {item}
      </MotionLI>
    );
  })}
</MotionUL>

MotionLI.jsx组件部分

import React from 'react';
import { dropdownLiAnimVariant } from '../assets/constants';
import { motion } from 'framer-motion';

const MotionLI = ({
  children,
  className,
  onClick,
  key,
  role,
  ariaPressed,
  tabIndex,
  onKeyDown, // 添加onKeyDown属性接收
}) => {
  return (
    <motion.li
      className={className}
      onClick={onClick}
      variants={dropdownLiAnimVariant}
      whileTap={{ scale: 0.9 }}
      key={key}
      role={role}
      aria-pressed={ariaPressed}
      tabIndex={tabIndex}
      onKeyDown={onKeyDown} // 传递onKeyDown事件到底层元素
    >
      {children}
    </motion.li>
  );
};

export default MotionLI;

验证步骤

测试时先通过Tab键将焦点切换到目标列表项,再按下回车/空格或其他按键,此时控制台应能正常输出内容。

内容的提问来源于stack exchange,提问作者Ishraque

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 15:40:48