导航栏滚动或窗口缩放时收缩功能异常的技术问询
解决导航栏双场景收缩的逻辑冲突问题
我明白你的问题了——当前代码里resize和scroll事件的逻辑互相干扰,导致收缩效果不符合预期对吧?咱们一步步来调整:
首先,先拆解核心需求:
- 场景1:窗口在
100px ≤ 宽度 ≤770px区间时,导航栏始终收缩,和滚动无关 - 场景2:窗口宽度不在这个区间时,滚动距离≥1则收缩,回滚到顶部则恢复
原代码的几个问题
- scroll事件里的
mQ.match是拼写错误,应该是mQ.matches $(this).scrollTop是方法,需要加括号调用:$(this).scrollTop()- resize和scroll事件里重复写了添加/移除类的代码,冗余且容易出错
- 逻辑判断没有明确优先级:媒体查询的场景应该优先于滚动场景
优化后的代码方案
咱们把重复的操作抽成一个函数,然后梳理清楚判断逻辑:
$(document).ready(function() { var logo = $('.logo'); var topLevelListItems = $('.mainNav li'); var mQ = window.matchMedia('(min-width: 100px) and (max-width: 770px)'); // 抽离统一的收缩/恢复函数,避免重复代码 function toggleNavShrink(shouldShrink) { $('nav').toggleClass('shrink', shouldShrink); $('.nav-fixedWidth').toggleClass('shrink', shouldShrink); logo.toggleClass('shrink', shouldShrink); topLevelListItems.toggleClass('shrink', shouldShrink); } // 处理窗口 resize 事件 function handleResize() { if (mQ.matches) { // 场景1:媒体查询匹配,强制收缩 toggleNavShrink(true); } else { // 场景2:媒体查询不匹配,根据当前滚动状态调整 var isScrolled = $(window).scrollTop() >= 1; toggleNavShrink(isScrolled); } } // 处理滚动事件 function handleScroll() { // 只有媒体查询不匹配时,才根据滚动调整 if (!mQ.matches) { var isScrolled = $(window).scrollTop() >= 1; toggleNavShrink(isScrolled); } // 媒体查询匹配时,保持收缩,不处理滚动 } // 初始化时先执行一次resize逻辑,确保初始状态正确 handleResize(); // 绑定事件 $(window).resize(handleResize); $(window).scroll(handleScroll); });
代码解释
toggleNavShrink函数:用toggleClass的第二个参数(布尔值)来统一控制所有元素的shrink类,避免重复写四次addClass/removeClass,代码更简洁易维护。- 优先级明确:媒体查询的场景优先——只要窗口在100-770px区间,不管怎么滚动都保持收缩;只有窗口超出这个区间,才会响应滚动事件来切换收缩状态。
- 初始化执行:页面加载时先运行
handleResize,确保导航栏一开始就处于正确的状态,不会出现初始状态错误的问题。 - 修正了原代码的语法错误:比如
scrollTop()的调用和mQ.matches的正确拼写。
这样调整后,两种场景的逻辑就不会互相抵消了,导航栏的收缩行为会完全符合你的预期~
内容的提问来源于stack exchange,提问作者Theodore Steiner
相关产品推荐
相关产品推荐

