滚动到dark类Div时切换粘性头部Logo问题:仅首个Div生效,后续失效
多区域滚动切换粘性头部Logo解决方案
之前的实现只检测了第一个.dark元素的位置,没有遍历所有区块判断当前滚动位置落在哪个区域内,导致后续的.dark区域无法触发Logo切换。下面是修复后的完整实现:
HTML 调整(可选,优化操作便利性)
给Logo添加ID方便定位,同时给区块添加高度便于测试:
<header id="masthead"> <img id="site-logo" src="my_logo.png" alt="默认Logo"> </header> <div class="dark" style="height: 800px; background: #333;"></div> <div class="light" style="height: 800px; background: #fff;"></div> <div class="dark" style="height: 800px; background: #333;"></div> <div class="light" style="height: 800px; background: #fff;"></div>
jQuery 实现代码
$(document).ready(function() { const $masthead = $('#masthead'); const $logo = $('#site-logo'); const defaultLogoSrc = 'my_logo.png'; const darkLogoSrc = 'my_logo_dark.png'; // 替换为你的深色Logo地址 const headerHeight = $masthead.outerHeight(); function updateLogoState() { let isInDarkArea = false; // 加上头部高度,匹配用户实际可视的内容区域位置 const currentScrollPos = $(window).scrollTop() + headerHeight; // 遍历所有深色区块,判断当前滚动位置是否落在区块范围内 $('.dark').each(function() { const blockTop = $(this).offset().top; const blockBottom = blockTop + $(this).outerHeight(); if (currentScrollPos >= blockTop && currentScrollPos < blockBottom) { isInDarkArea = true; return false; // 找到匹配区块后停止遍历,提升性能 } }); // 切换Logo,避免重复修改DOM属性 if (isInDarkArea && $logo.attr('src') !== darkLogoSrc) { $logo.attr('src', darkLogoSrc); } else if (!isInDarkArea && $logo.attr('src') !== defaultLogoSrc) { $logo.attr('src', defaultLogoSrc); } } // 页面加载完成后先执行一次,初始化Logo状态 updateLogoState(); // 绑定滚动事件,实时检测位置并更新Logo $(window).on('scroll', updateLogoState); });
核心修复说明
- 替换
position().top为offset().top:前者是元素相对父容器的位置,后者是相对文档顶部的绝对位置,滚动判断必须用绝对位置才能准确匹配区域。 - 遍历所有
.dark区块:每次滚动时逐个检查当前位置是否落在深色区域内,只要命中任意一个就切换深色Logo。 - 叠加头部高度:由于头部是粘性固定在顶部的,用户实际看到的内容从头部下方开始,需要把滚动位置加上头部高度才能准确对应到区块位置。
- 减少无效DOM操作:切换前先判断当前Logo是否已经是目标状态,避免重复修改
src属性。
内容的提问来源于stack exchange,提问作者Nicolas Poiteau
相关产品推荐
相关产品推荐

