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

MUI Swipeable Drawer高度调整时卡顿问题求助

MUI Swipeable Drawer 视图高度变化卡顿至底部的问题修复方案

问题说明

MUI的Swipeable Drawer存在异常:当视图高度变化时(比如调整窗口大小、切换响应式预览),抽屉会卡顿到底部位置。这个问题在iOS Safari新版本中尤其突出——浏览器底部搜索栏滚动隐藏时,会频繁触发视口高度变化,导致抽屉反复卡顿。

当前代码中,通过Global组件给抽屉设置了高度样式:

<Global
  styles={{
    '.MuiDrawer-root > .MuiPaper-root': {
      height: `calc(50% - ${drawerBleeding}px)`,
      overflow: 'visible',
    },
  }}
/>

如果注释掉上述代码里的height属性,抽屉功能会恢复正常,但会出现新问题:页面刷新后抽屉直接消失,必须点击开关按钮打开再关闭才能正常显示。

修复思路与代码示例

1. 动态监听视口变化,实时更新抽屉高度

不再依赖静态样式计算,而是监听窗口尺寸变化(包括iOS的视口调整),实时更新抽屉高度,避免样式不匹配导致的卡顿:

import { useEffect, useState } from 'react';
import { SwipeableDrawer, Global } from '@mui/material';

const CustomSwipeableDrawer = ({ open, onClose, onOpen }) => {
  const drawerBleeding = 16; // 根据业务配置调整该值
  const [drawerHeight, setDrawerHeight] = useState(`calc(50% - ${drawerBleeding}px)`);

  useEffect(() => {
    const updateDrawerHeight = () => {
      // 重新计算高度,适配当前视口
      setDrawerHeight(`calc(50% - ${drawerBleeding}px)`);
    };

    // 监听窗口 resize 和 设备旋转事件
    window.addEventListener('resize', updateDrawerHeight);
    window.addEventListener('orientationchange', updateDrawerHeight);

    // 组件卸载时移除监听
    return () => {
      window.removeEventListener('resize', updateDrawerHeight);
      window.removeEventListener('orientationchange', updateDrawerHeight);
    };
  }, [drawerBleeding]);

  return (
    <>
      <Global
        styles={{
          '.MuiDrawer-root > .MuiPaper-root': {
            height: drawerHeight,
            overflow: 'visible',
          },
        }}
      />
      <SwipeableDrawer
        open={open}
        onClose={onClose}
        onOpen={onOpen}
        {/* 其他抽屉配置属性 */}
      >
        {/* 抽屉内容区域 */}
      </SwipeableDrawer>
    </>
  );
};

2. 使用自定义类名替代全局样式覆盖

直接修改MUI默认类名容易引发样式冲突,建议给抽屉的Paper组件添加自定义类名,精准控制样式:

<SwipeableDrawer
  PaperProps={{
    className: 'custom-drawer-paper',
  }}
  open={open}
  onClose={onClose}
  onOpen={onOpen}
>
  {/* 抽屉内容 */}
</SwipeableDrawer>

<Global
  styles={{
    '.custom-drawer-paper': {
      height: drawerHeight,
      overflow: 'visible',
    },
  }}
/>

3. 解决刷新后抽屉消失的问题

确保抽屉的open状态在组件初始化时正确设置,比如根据业务需求设置初始值,或者从本地存储读取状态:

// 示例:初始状态设为打开,或根据业务逻辑调整
const [open, setOpen] = useState(true);

也可以在组件挂载时,强制触发一次状态更新或重绘,确保DOM渲染正常。

内容的提问来源于stack exchange,提问作者Alex-Pober

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:25:19