Svelte Store中Escape按键事件无法关闭模态框问题
问题分析与修复方案
你的问题核心是Escape按键触发关闭后,store状态未同步更新,导致视图没响应。虽然外部visible变量已变为false,但Svelte视图依赖的是$ModalStore的状态,而这个状态并没有被更新。
问题根源
- 外部
visible变量与store内部状态是分离的,closeModal只修改了外部变量,没有调用store的set方法同步状态; 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
相关产品推荐
相关产品推荐

