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

React响应式页面窄屏下按钮唤出遮罩式SideBar实现方案

窄屏遮罩式侧边栏实现方案

核心实现逻辑

  • 新增独立的移动端侧边栏显隐状态,和宽屏下的自动展示逻辑解耦
  • 窗口宽度变化时做状态兜底:宽度拉到600px以上时,自动关闭移动端遮罩式侧边栏,避免样式冲突
  • 窄屏下侧边栏改为固定定位悬浮展示,叠加半透明遮罩层,配套唤出/关闭按钮
  • 点击遮罩层、关闭按钮时,自动收起侧边栏
  • 原有宽屏侧边栏逻辑完全保留,不影响桌面端使用体验

具体代码修改

1. App.jsx 逻辑调整

原有WindowSize.jsx代码无需改动,仅需修改App组件,新增状态控制、窄屏专属交互元素:

import { useState, useEffect } from 'react';
// 其余原有导入项保持不变

export default function App() {
  const size = WindowSize();
  // 新增:移动端遮罩侧边栏显隐控制状态
  const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
  // 其余原有业务状态(如filters等)保持不变

  // 窗口宽度超过600px时,自动重置移动端侧边栏状态
  useEffect(() => {
    if (size.width > 600 && mobileSidebarOpen) {
      setMobileSidebarOpen(false);
    }
  }, [size.width, mobileSidebarOpen])

  return (
    <ThemeProvider theme={theme}>
      <BrowserRouter>
        <AppContext.Provider value={{ filters, setFilters}}>
          <div style={{display: 'flex', position: 'relative', minHeight: '100vh'}}>
            {/* 宽屏常驻侧边栏 逻辑保持原有规则 */}
            {size.width > 600 && <Sidebar />}

            {/* 窄屏侧边栏唤出按钮 */}
            {size.width <= 600 && (
              <button 
                onClick={() => setMobileSidebarOpen(true)}
                style={{
                  position: 'fixed',
                  left: '16px',
                  top: '16px',
                  zIndex: 99,
                  padding: '8px 12px',
                  borderRadius: '4px',
                  border: '1px solid #eee',
                  background: '#fff'
                }}
              >
                筛选
              </button>
            )}

            {/* 窄屏遮罩层+悬浮侧边栏 仅在状态开启时渲染 */}
            {size.width <= 600 && mobileSidebarOpen && (
              <>
                {/* 半透明遮罩 点击关闭侧边栏 */}
                <div 
                  onClick={() => setMobileSidebarOpen(false)}
                  style={{
                    position: 'fixed',
                    inset: 0,
                    background: 'rgba(0,0,0,0.5)',
                    zIndex: 999
                  }}
                />
                {/* 悬浮侧边栏容器 */}
                <div
                  style={{
                    position: 'fixed',
                    left: 0,
                    top: 0,
                    height: '100vh',
                    width: '280px',
                    background: '#fff',
                    zIndex: 1000,
                    overflowY: 'auto',
                    boxShadow: '2px 0 8px rgba(0,0,0,0.15)',
                    padding: '48px 16px 16px'
                  }}
                >
                  {/* 侧边栏关闭按钮 */}
                  <button
                    onClick={() => setMobileSidebarOpen(false)}
                    style={{
                      position: 'absolute',
                      right: '12px',
                      top: '12px',
                      border: 'none',
                      background: 'transparent',
                      fontSize: '20px',
                      cursor: 'pointer'
                    }}
                  >
                    ×
                  </button>
                  {/* 复用原有Sidebar组件 无需修改组件内部代码 */}
                  <Sidebar />
                </div>
              </>
            )}

            <Routes>
              <Route exact path='/devices/' element={<PockId />} />
              <Route path="*" element={<Navigate to="/devices" replace />} />
            </Routes>
          </div>
        </AppContext.Provider>
      </BrowserRouter>
    </ThemeProvider>
  );
}

2. 体验优化项

  • 给遮罩层、侧边栏增加200ms左右的CSS过渡动画,实现淡入、左侧滑入效果,避免生硬切换
  • 侧边栏打开时,给document.body添加overflow: hidden样式,禁止背景页面滚动,关闭时移除该样式
  • 唤出按钮、关闭按钮的样式、位置可根据站点现有设计规范调整,避免和页面其他固定定位元素重叠
  • 侧边栏宽度可根据实际内容宽度调整,通常设置为280px-320px即可满足窄屏展示需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 05:18:53