滚动触发的跑马灯文本重载页面后滚动时出现大幅偏移问题
修复滚动驱动跑马灯的重载偏移问题
问题根源
- 初始状态未同步:页面重载时如果已有滚动位置,
scroll事件不会自动触发,跑马灯没有初始偏移值,第一次滚动时突然应用当前视口偏移量,导致大幅跳动。 - 元素关联错误:所有
.marqueeText都使用当前遍历的.marqueeContainer的偏移值,多个跑马灯容器会互相干扰,导致偏移逻辑混乱。 - 冗余的事件嵌套:在
scroll事件内每次遍历都创建animate函数并嵌套requestAnimationFrame,既浪费性能也可能导致执行时机冲突。
修复后的代码
HTML(无需修改)
<div class="marqueeContainer"> <div class="marqueeText"> <h1>Endrit</h1> <h1>As</h1> </div> <div class="marqueeText"> <h1>Artan</h1> </div> </div> <div class="container"> <h2>Hahahahahah</h2> <h2>Hahahahahah</h2> <h2>Hahahahahah</h2> <h2>Hahahahahah</h2> <h2>Hahahahahah</h2> <h2>Hahahahahah</h2> <h2>Hahahahahah</h2> <h2>Hahahahahah</h2> <h2>Hahahahahah</h2> <h2>Hahahahahah</h2> <h2>Hahahahahah</h2> </div> <div class="marqueeContainer"> <div class="marqueeText"> <h1>Endrit</h1> <h1>As</h1> </div> <div class="marqueeText"> <h1>Artan</h1> </div> </div>
CSS(无需修改)
.marqueeContainer{ display:inline-flex; width:100%; overflow:hidden; } .marqueeText{ min-width:100%; display:inline-flex; } .marqueeText *{ margin:0 1rem; }
JavaScript(修复版)
const marqueeContainers = document.querySelectorAll(".marqueeContainer"); // 初始化+滚动时更新跑马灯位置的函数 function updateMarqueePosition() { marqueeContainers.forEach(container => { // 获取当前容器相对于视口的Y偏移 const containerY = container.getBoundingClientRect().y; // 只操作当前容器下的.marqueeText,避免跨容器干扰 const texts = container.querySelectorAll(".marqueeText"); texts.forEach(text => { text.style.transform = `translateX(${containerY}px)`; }); }); } // 页面加载时立即同步位置,解决重载偏移问题 window.addEventListener('load', updateMarqueePosition); // 滚动时更新位置,用requestAnimationFrame优化性能 window.addEventListener('scroll', () => { requestAnimationFrame(updateMarqueePosition); });
关键修改点
- 初始同步:添加
load事件监听,页面加载完成后立即执行一次位置更新,确保重载后跑马灯直接处于正确位置。 - 容器与文本绑定:每个容器只操作自己内部的
.marqueeText,避免多个容器的偏移值互相覆盖。 - 性能优化:将位置更新逻辑抽离为独立函数,滚动时通过
requestAnimationFrame调度,避免频繁DOM操作,同时避免重复创建函数。
内容的提问来源于stack exchange,提问作者Endritibra
相关产品推荐
相关产品推荐

