如何使用window.matchMedia()结合jQuery适配屏幕尺寸并更新DOM?
使用window.matchMedia() + jQuery处理响应式座位选择UI
核心思路
window.matchMedia() 可以直接监听CSS媒体查询的状态变化,相比 window.onresize 能精准定位断点,避免频繁触发回调,非常适合处理响应式场景下的DOM更新逻辑。下面结合座位选择UI给出完整示例,涵盖不同屏幕尺寸下的座位布局、尺寸调整及状态同步。
完整示例代码
HTML结构
<div class="seat-container"> <div class="row"> <div class="seat" data-seat-id="1"></div> <div class="seat occupied" data-seat-id="2"></div> <div class="seat" data-seat-id="3"></div> <div class="seat selected" data-seat-id="4"></div> </div> <div class="row"> <div class="seat" data-seat-id="5"></div> <div class="seat" data-seat-id="6"></div> <div class="seat occupied" data-seat-id="7"></div> <div class="seat" data-seat-id="8"></div> </div> <div class="seat-status"> <span class="status-item"><span class="seat"></span> 可选</span> <span class="status-item"><span class="seat selected"></span> 已选</span> <span class="status-item"><span class="seat occupied"></span> 已占</span> </div> </div>
CSS样式(配合媒体查询)
.seat-container { max-width: 800px; margin: 2rem auto; padding: 0 1rem; } .row { display: flex; justify-content: center; gap: 0.5rem; margin-bottom: 0.8rem; } .seat { width: 40px; height: 40px; background: #ddd; border-radius: 4px; cursor: pointer; transition: all 0.2s; } .seat.selected { background: #4CAF50; } .seat.occupied { background: #f44336; cursor: not-allowed; } .seat-status { display: flex; justify-content: center; gap: 2rem; margin-top: 1.5rem; } .status-item { display: flex; align-items: center; gap: 0.5rem; } /* 响应式断点 */ @media (max-width: 600px) { .seat { width: 30px; height: 30px; } .row { gap: 0.3rem; margin-bottom: 0.6rem; } .seat-status { gap: 1rem; } }
JavaScript逻辑(jQuery + matchMedia)
// 定义媒体查询断点 const desktopQuery = window.matchMedia('(min-width: 601px)'); const mobileQuery = window.matchMedia('(max-width: 600px)'); // 核心处理函数:根据屏幕尺寸更新DOM行为/结构 function updateSeatUI(mediaQuery) { const $seats = $('.seat:not(.occupied)'); if (mediaQuery.matches) { // 桌面端逻辑:添加hover效果,增强交互反馈 $seats.hover( function() { $(this).css('transform', 'scale(1.1)'); }, function() { $(this).css('transform', 'scale(1)'); } ); // 移除移动端触摸事件,避免冲突 $seats.off('touchstart'); } else { // 移动端逻辑:移除hover(触摸设备无需),添加触摸选中逻辑 $seats.off('mouseenter mouseleave'); $seats.on('touchstart', function(e) { e.preventDefault(); $(this).toggleClass('selected'); }); } // 自适应居中座位行 const containerWidth = $('.seat-container').width(); const rowWidth = $('.row').width(); $('.row').css('margin-left', (containerWidth - rowWidth) / 2 + 'px'); } // 页面加载时初始化UI状态 updateSeatUI(desktopQuery.matches ? desktopQuery : mobileQuery); // 监听媒体查询变化,触发UI更新 desktopQuery.addEventListener('change', (e) => { if (e.matches) updateSeatUI(desktopQuery); }); mobileQuery.addEventListener('change', (e) => { if (e.matches) updateSeatUI(mobileQuery); }); // 通用座位点击选中逻辑 $('.seat:not(.occupied)').on('click', function() { $(this).toggleClass('selected'); });
关键注意事项
- 初始化执行:页面加载时必须先调用一次处理函数,避免初始状态下UI异常。
- 事件解绑:切换断点时要解绑之前绑定的事件,防止事件冲突或重复触发。
- 样式与逻辑分离:样式调整优先用CSS媒体查询,JS只处理DOM行为(如事件绑定、布局计算),减少冗余代码。
- 性能优化:缓存jQuery对象(如
$seats),避免重复查询DOM,提升响应速度。
内容的提问来源于stack exchange,提问作者Charles
相关产品推荐
相关产品推荐

