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

Svelte Store中Escape按键事件无法关闭模态框问题

问题分析与修复方案

你的问题核心是Escape按键触发关闭后,store状态未同步更新,导致视图没响应。虽然外部visible变量已变为false,但Svelte视图依赖的是$ModalStore的状态,而这个状态并没有被更新。

问题根源

  1. 外部visible变量与store内部状态是分离的,closeModal只修改了外部变量,没有调用store的set方法同步状态;
  2. closeOnEscape调用closeModal后,store的值仍保持为true,所以{#if $ModalStore}的条件依然成立,模态框不会关闭。

修复后的代码

将状态完全交给store管理,移除外部visible变量,确保所有状态变更都通过store方法同步:

import { writable } from "svelte/store";

const createModalStore = () => {
    const { subscribe, set } = writable(false);
    
    const closeOnEscape = (e: KeyboardEvent) => {
        if (e.key === 'Escape') {
            set(false);
            document.removeEventListener('keydown', closeOnEscape);
        }
    };

    return {
        subscribe,
        openModal: () => {
            set(true);
            document.addEventListener('keydown', closeOnEscape);
            document.body.style.overflow = 'hidden'; // 可选:打开时锁定页面滚动
        },
        closeModal: () => {
            set(false);
            document.removeEventListener('keydown', closeOnEscape);
            document.body.style.overflow = 'auto';
        },
        // 订阅取消时清理监听,防止内存泄漏
        unsubscribe: () => {
            document.removeEventListener('keydown', closeOnEscape);
            document.body.style.overflow = 'auto';
        }
    };
};

export default createModalStore();

关键改动说明

  • 移除了外部visible变量,所有状态由store内部维护,避免同步问题;
  • closeOnEscape直接调用set(false)更新store状态,同时移除键盘监听;
  • openModal和closeModal方法中,同步处理状态更新与事件监听的添加/移除;
  • 可选添加页面滚动锁定/恢复的逻辑,提升模态框体验。

模态框渲染代码保持不变

{#if $ModalStore}
   <div>Modal Popup</div>
{/if}

现在按下Escape键时,store状态会立即更新为false,视图会自动响应关闭模态框。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:10:37