# 响应式设计指南 - 不使用媒体查询 ## 概述 本指南介绍如何使用 JavaScript 检测屏幕尺寸来替代传统的 CSS 媒体查询,实现更灵活、更可控的响应式设计。 ## 解决方案架构 ### 1. CSS 容器查询 (Container Queries) - **文件**: `src/assets/css/responsive_without_media.css` - **优势**: 最新的 CSS 标准,基于容器而非视口 - **兼容性**: 现代浏览器支持 ### 2. JavaScript 检测 + 类名控制 - **文件**: `src/static/responsive_helper.js` - **优势**: 完全兼容,可编程控制 - **兼容性**: 所有浏览器支持 ### 3. Vue2 组件化响应式 - **文件**: `src/components/ResponsiveLayout.vue` - **优势**: 组件化,易于维护 - **兼容性**: Vue2 项目 ## 使用方法 ### 基础使用 #### 1. 引入响应式助手 ```html ``` #### 2. 使用响应式布局组件 ```vue ``` #### 3. 使用响应式 CSS 类 ```html
超小屏幕隐藏
小屏幕隐藏
中等屏幕隐藏
大屏幕隐藏
超大屏幕隐藏
超小屏幕显示
小屏幕显示
中等屏幕显示
大屏幕显示
超大屏幕显示
``` ### 高级使用 #### 1. 自定义断点 ```vue ``` #### 2. 响应式内容控制 ```vue ``` #### 3. 动态样式调整 ```vue ``` ## CSS 类名系统 ### 响应式断点类名 ```css /* 屏幕尺寸类名 */ .screen-xs { /* 超小屏幕样式 */ } .screen-sm { /* 小屏幕样式 */ } .screen-md { /* 中等屏幕样式 */ } .screen-lg { /* 大屏幕样式 */ } .screen-xl { /* 超大屏幕样式 */ } .screen-xxl { /* 超超大屏幕样式 */ } /* 容器尺寸类名 */ .container-xs { /* 超小容器样式 */ } .container-sm { /* 小容器样式 */ } .container-md { /* 中等容器样式 */ } .container-lg { /* 大容器样式 */ } .container-xl { /* 超大容器样式 */ } .container-xxl { /* 超超大容器样式 */ } ``` ### 响应式工具类 ```css /* 显示/隐藏 */ .responsive-hidden-xs { display: none !important; } .responsive-visible-xs { display: block !important; } /* 布局 */ .responsive-grid { display: grid !important; } .responsive-flex { display: flex !important; } .responsive-block { display: block !important; } /* 间距 */ .responsive-m-0 { margin: 0 !important; } .responsive-p-3 { padding: 1rem !important; } /* 文本 */ .responsive-text-center { text-align: center; } .responsive-text-primary { color: #3498db; } /* 阴影 */ .responsive-shadow { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } .responsive-shadow-lg { box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1); } ``` ## JavaScript API ### 全局方法 ```javascript // 响应式显示元素 window.responsiveShow(element, breakpoint); // 响应式隐藏元素 window.responsiveHide(element, breakpoint); // 响应式切换类名 window.responsiveToggleClass(element, className, breakpoint); // 获取当前屏幕信息 const screenInfo = window.responsiveHelper.getCurrentScreenInfo(); ``` ### 事件监听 ```javascript // 监听屏幕尺寸变化 window.addEventListener('screenSizeChange', (event) => { const { size, width, height, breakpoint } = event.detail; if (size === 'xs' || size === 'sm' || size === 'md') { // 移动端逻辑 console.log('切换到移动端'); } else if (size === 'lg') { // 平板端逻辑 console.log('切换到平板端'); } else { // 桌面端逻辑 console.log('切换到桌面端'); } }); ``` ### 断点检测 ```javascript // 检查是否匹配特定断点 const isMobile = window.responsiveHelper.matchesBreakpoint('md'); const isTablet = window.responsiveHelper.matchesBreakpoint('lg'); const isDesktop = !window.responsiveHelper.matchesBreakpoint('lg'); ``` ## 最佳实践 ### 1. 性能优化 ```javascript // 使用防抖优化 resize 事件 let resizeTimeout; window.addEventListener('resize', () => { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(() => { // 执行响应式逻辑 }, 100); }); ``` ### 2. 渐进增强 ```javascript // 检测功能支持 if (CSS.supports('container-type', 'inline-size')) { // 使用容器查询 console.log('支持容器查询'); } else { // 回退到 JavaScript 检测 console.log('使用 JavaScript 检测'); } ``` ### 3. 组件化设计 ```vue ``` ### 4. 主题切换 ```javascript // 根据屏幕尺寸切换主题 function switchThemeByScreen() { const screenInfo = window.responsiveHelper.getCurrentScreenInfo(); if (screenInfo.isMobile) { document.body.classList.add('theme-mobile'); document.body.classList.remove('theme-desktop'); } else { document.body.classList.add('theme-desktop'); document.body.classList.remove('theme-mobile'); } } // 监听屏幕变化 window.addEventListener('screenSizeChange', switchThemeByScreen); ``` ## 迁移指南 ### 从媒体查询迁移 #### 原来的 CSS ```css @media (max-width: 768px) { .mobile-menu { display: block; } .desktop-menu { display: none; } } ``` #### 新的 JavaScript 方式 ```javascript // 在组件中 mounted() { this.updateMenuVisibility(); window.addEventListener('screenSizeChange', this.updateMenuVisibility); }, methods: { updateMenuVisibility() { const mobileMenu = this.$el.querySelector('.mobile-menu'); const desktopMenu = this.$el.querySelector('.desktop-menu'); if (this.$refs.responsiveLayout.isMobile) { mobileMenu.style.display = 'block'; desktopMenu.style.display = 'none'; } else { mobileMenu.style.display = 'none'; desktopMenu.style.display = 'block'; } } } ``` #### 新的 CSS 类方式 ```css /* 使用响应式类名 */ .mobile-menu { display: none; } .desktop-menu { display: block; } /* 移动端显示 */ .screen-xs .mobile-menu, .screen-sm .mobile-menu, .screen-md .mobile-menu { display: block; } .screen-xs .desktop-menu, .screen-sm .desktop-menu, .screen-md .desktop-menu { display: none; } ``` ## 调试和测试 ### 1. 启用调试模式 ```vue ``` ### 2. 控制台调试 ```javascript // 查看当前屏幕信息 console.log(window.responsiveHelper.getCurrentScreenInfo()); // 手动触发屏幕变化 window.dispatchEvent(new Event('resize')); ``` ### 3. 测试不同屏幕尺寸 ```javascript // 模拟不同屏幕尺寸 function simulateScreenSize(width) { Object.defineProperty(window, 'innerWidth', { writable: true, configurable: true, value: width }); window.dispatchEvent(new Event('resize')); } // 测试移动端 simulateScreenSize(375); // 测试平板端 simulateScreenSize(768); // 测试桌面端 simulateScreenSize(1200); ``` ## 总结 通过使用 JavaScript 检测屏幕尺寸替代媒体查询,我们获得了: 1. **更好的控制性**: 可以编程控制响应式行为 2. **更高的灵活性**: 支持复杂的响应式逻辑 3. **更好的性能**: 避免 CSS 重排和重绘 4. **更好的维护性**: 集中管理响应式逻辑 5. **更好的兼容性**: 支持所有浏览器 这种方案特别适合需要复杂响应式逻辑的现代 Web 应用。