移动端点击导航后滚动时active类未正常移除的问题求助
搞定移动端滚动时导航active类不消失的问题
我看了你的代码和问题描述,桌面端滚动时导航的active类能正常移除,但移动端点击导航后再滚动,active类就赖着不走了对吧?这个问题大概率是因为你手动给导航项加的active类,在滚动事件里没被正确覆盖掉,咱们来一步步解决它。
问题出在哪?
你现在的滚动逻辑是通过滚动位置匹配section来添加/移除active类,但移动端点击导航后手动添加的active类,在滚动时如果当前位置没对应到那个section,原来的代码只会移除对应section索引的导航项的active类,而手动加的那个可能不在这个匹配逻辑里,就导致它一直保留着。
解决方案
咱们调整两个地方的逻辑,就能让移动端和桌面端表现一致:
1. 先清后加,滚动时先移除所有active类
修改addActiveOnScroll函数,一开始就把所有导航项的active类都移除,再根据滚动位置添加对应的。这样不管之前手动加了哪个,都会被先清掉,再重新匹配:
function addActiveOnScroll() { const navListItem = document.querySelectorAll('.nav_list-item') const btnItem = document.querySelector('.hire-btn'); const sections = document.querySelectorAll("section"); const scrollY = window.pageYOffset; // 先把所有导航项的active类都移除,这一步是关键! navListItem.forEach(item => item.classList.remove('active')); // 再根据滚动位置匹配section,添加对应的active类 sections.forEach((current, key) => { const sectionHeight = current.offsetHeight; const sectionTop = current.offsetTop - 100; if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) { // 要确保索引对应的导航项存在,避免报错 if (navListItem[key]) { navListItem[key].classList.add('active'); } } }); // 页面底部的逻辑保持不变 if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) { navListItem.forEach(item => item.classList.remove('active')); btnItem.classList.add('active'); } }
2. (可选)给移动端触摸滚动也绑定事件
有时候移动端的scroll事件触发可能有点延迟,加上touchmove事件监听,确保触摸滚动时也能及时触发active类的更新:
window.addEventListener('touchmove', addActiveOnScroll);
3. 点击事件小优化(可选)
点击导航时可以考虑阻止默认跳转行为(如果你的锚点跳转不需要即时生效的话),避免页面跳转干扰滚动事件的触发:
nav_lists.forEach(e => { e.addEventListener('click', (event) => { // 如果不需要立即跳转,可以加上这行 // event.preventDefault(); nav_lists.forEach(el => el.classList.remove('active')); e.classList.add('active'); }); });
原理说明
原来的逻辑是“逐个检查section,移除不匹配项的active类”,但手动添加的active类不在这个检查范围内,就会残留。现在改成“先清空所有active类,再添加匹配的”,相当于每次滚动都重新计算状态,完全覆盖了手动添加的状态,自然就不会有残留了。
内容的提问来源于stack exchange,提问作者Surge
相关产品推荐
相关产品推荐

