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

React+styled-components项目监听ESC键关闭Drawer模态框实现咨询

实现ESC键关闭抽屉的方案

核心实现逻辑

  • 在Drawer组件内部监听键盘事件,逻辑内聚不污染父组件
  • 仅在抽屉打开时绑定事件监听,减少不必要的性能消耗
  • 组件卸载/抽屉关闭时自动移除监听,避免内存泄漏

具体代码修改

修改Drawer组件代码

import React, { useEffect } from "react";
import styled from "styled-components";

type Props = {
  isOpen: boolean;
  padding?: number;
  children: React.ReactNode;
  onClose: () => void;
};

export default (props: Props) => {
  // 新增ESC键监听逻辑
  useEffect(() => {
    if (!props.isOpen) return;
    
    const handleEscPress = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        props.onClose();
      }
    };

    window.addEventListener('keydown', handleEscPress);
    return () => window.removeEventListener('keydown', handleEscPress);
  }, [props.isOpen, props.onClose]);

  return (
    <>
      <Overlay isOpen={props.isOpen} onClick={props.onClose} />
      <DrawerModal {...props}>{props.children}</DrawerModal>
    </>
  );
};

const DrawerModal = styled.div<Props>`
  position: absolute;
  overflow: scroll;
  top: 0;
  right: 0;
  height: 100vh;
  width: ${({ isOpen }: Props) => (isOpen ? 400 : 0)}px;
  background: blue;
  box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.25);
  transition: 200ms cubic-bezier(0.25, 0.1, 0.24, 1);
`;

const Overlay = styled.div<{ isOpen: boolean }>`
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: ${(props: { isOpen: boolean }) => (props.isOpen ? 0 : -1)};
`;

App组件无需修改

原有App代码可以直接保留使用,所有关闭逻辑已经封装在Drawer组件内部,不影响原有调用方式。

补充说明

这里使用e.key === 'Escape'判断而不是废弃的keyCode属性,符合最新的Web标准,兼容性覆盖所有主流现代浏览器。如果需要兼容非常老旧的浏览器,可以补充e.keyCode === 27的判断条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 11:48:02