滚动时依据当前section类名修改固定SVG logo颜色的实现方案?
滚动监听修改SVG Logo颜色实现方案
核心实现逻辑
- 提前配置需要触发logo变色的section类名与对应logo样式类的映射关系,后续可灵活扩展
- 滚动时通过
getBoundingClientRect()获取每个section的视口位置,判断section是否处于有效可见区域 - 匹配到对应section时先清空所有自定义logo类,再添加对应样式类,无匹配时自动恢复默认样式
- 增加节流函数优化scroll事件触发频率,避免性能损耗,同时设置判定阈值避免边界位置样式闪烁
完整可运行代码
(() => { const logo = document.querySelector('.logo'); const sections = document.querySelectorAll('section'); if(!sections.length || !logo) { return; } // 配置映射关系:key为section的类名,value为要给logo添加的类名,可自行扩展 const logoClassMap = { 'intro': 'logo--white', 'projects': 'logo--black' } // 节流函数,控制scroll事件触发频率,默认100ms const throttle = (func, delay = 100) => { let timer = null; return function(...args) { if(!timer) { timer = setTimeout(() => { func.apply(this, args); timer = null; }, delay) } } } const onPageScroll = () => { const viewportHeight = window.innerHeight; let targetLogoClass = null; sections.forEach(section => { const rect = section.getBoundingClientRect(); // 判定规则:section在视口30%~70%区域内时判定为当前活跃section,可自行调整阈值 const isActive = rect.top < viewportHeight * 0.7 && rect.bottom > viewportHeight * 0.3; if(isActive) { // 检查当前section是否有匹配的类名 section.classList.forEach(cls => { if(logoClassMap[cls]) { targetLogoClass = logoClassMap[cls]; } }) } }) // 先清空所有自定义logo类 Object.values(logoClassMap).forEach(cls => logo.classList.remove(cls)); // 有匹配的类则添加 if(targetLogoClass) { logo.classList.add(targetLogoClass); } } // 绑定带节流的滚动事件 window.addEventListener('scroll', throttle(onPageScroll)); // 页面初始加载主动触发一次,避免初始状态样式错误 onPageScroll(); })();
配套CSS示例
/* logo默认样式,固定定位 */ .logo { position: fixed; top: 16px; left: 16px; width: 80px; fill: #000; /* 默认颜色 */ transition: fill 0.3s ease; /* 颜色过渡更顺滑 */ } /* intro区域对应的logo白色样式 */ .logo--white { fill: #fff; } /* projects区域对应的logo黑色样式 */ .logo--black { fill: #000; }
扩展说明
如果需要新增其他section对应logo样式,直接在logoClassMap中添加键值对即可,无需修改逻辑代码。如果需要调整触发时机,修改isActive判定中的视口比例阈值即可。
内容的提问来源于stack exchange,提问作者user10431099
相关产品推荐
相关产品推荐

