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

DaisyUI抽屉关闭异常:SvelteKit下缩屏后仍展开的修复方法

修复SvelteKit+DaisyUI抽屉在屏幕尺寸变化后异常展开的问题

问题分析

你之前通过直接操作DOM切换checkbox状态的方案,会在以下场景失效:

  • 大屏下点击抽屉链接后,checkbox状态被切换为选中
  • 缩小屏幕到小屏断点时,lg:drawer-open类失效,但checkbox仍处于选中状态,导致抽屉保持展开

这是因为DaisyUI的抽屉在大屏时依赖lg:drawer-open强制显示,忽略checkbox状态;但小屏时完全由checkbox状态控制,直接操作DOM的方式无法同步屏幕尺寸变化后的状态。

修复方案

使用Svelte的响应式绑定+窗口尺寸监听,替代直接DOM操作,精准控制抽屉状态:

<script>
  import { onMount, onDestroy } from 'svelte';

  let isDrawerOpen = false;
  let resizeTimeout;
  // DaisyUI默认lg断点为1024px,可根据自定义配置调整
  const LG_BREAKPOINT = 1024;

  const isLargeScreen = () => window.innerWidth >= LG_BREAKPOINT;

  const handleResize = () => {
    clearTimeout(resizeTimeout);
    // 防抖处理,避免窗口 resize 频繁触发
    resizeTimeout = setTimeout(() => {
      // 大屏下重置抽屉状态,确保切回小屏时抽屉默认收起
      if (isLargeScreen()) {
        isDrawerOpen = false;
      } 
      // 小屏下直接关闭抽屉,解决缩小屏幕后抽屉残留展开的问题
      else {
        isDrawerOpen = false;
      }
    }, 200);
  };

  onMount(() => {
    window.addEventListener('resize', handleResize);
    // 初始加载时根据屏幕尺寸设置初始状态
    if (isLargeScreen()) {
      isDrawerOpen = false;
    }
  });

  onDestroy(() => {
    window.removeEventListener('resize', handleResize);
    clearTimeout(resizeTimeout);
  });

  // 点击链接时仅在小屏关闭抽屉
  const closeDrawer = () => {
    if (!isLargeScreen()) {
      isDrawerOpen = false;
    }
  };
</script>

<div class="drawer lg:drawer-open">
  <input 
    id="my-drawer-2" 
    type="checkbox" 
    class="drawer-toggle" 
    bind:checked={isDrawerOpen} 
  />
  <div class="drawer-content flex flex-col items-center justify-center">
    <label for="my-drawer-2" class="btn btn-primary drawer-button lg:hidden">Open drawer</label>
  </div> 
  <div class="drawer-side">
    <label for="my-drawer-2" class="drawer-overlay"></label> 
    <ul class="menu p-4 w-80 h-full bg-base-200 text-base-content">
      <li><a href='/' on:click={closeDrawer}>Home</a></li>
      <li><a href='/my-page' on:click={closeDrawer}>My page</a></li>
    </ul>
  </div>
</div>

方案说明

  1. 响应式绑定:用bind:checked={isDrawerOpen}将checkbox状态与Svelte变量绑定,替代原生DOM操作,状态变更更可控。
  2. 屏幕尺寸监听:通过resize事件+防抖处理,在屏幕切换时自动调整抽屉状态:
    • 大屏下强制重置isDrawerOpen为false,因为lg:drawer-open已确保抽屉显示,同时避免切回小屏时残留选中状态。
    • 小屏下直接关闭抽屉,解决缩小屏幕后抽屉异常展开的问题。
  3. 链接点击处理:仅在小屏模式下关闭抽屉,大屏下无需操作,符合抽屉的展示逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:25:39