# 响应式设计指南 - 不使用媒体查询
## 概述
本指南介绍如何使用 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 应用。