Ich habe 3 Blöcke, der zweite Block hat eine Linie und einen Rollkreis. Die Kreise scrollen mit dem Hauptscroll, und wenn das Scrollen stoppt, bleiben die Kreise am nächstgelegenen Punkt hängen, der die Mitte jedes Blocks ist
Aber ich habe hier dieses Problem: Wenn der Hauptscroll den zweiten Block kreuzt, hören die Kreise auf zu scrollen und verhalten sich auf der Seite falsch
Ist es möglich, das Skript so zu vervollständigen, dass es beim Kreuzen der Hauptrolle block2
时,圆圈将自动坚持最后一个案例并完全停止滚动?当我们返回并穿过 block2
entsprechend wieder funktionieren sollte
Im Allgemeinen liegt das Problem im letzten Fall: Wenn die Schriftrolle ihn erreicht, bewegt sich der Kreis nicht weiter. Vielleicht gibt es eine andere Lösung als die von mir vorgeschlagene Option
Ich möchte, dass das Scrollen von block2
Anfang bis Ende reibungslos verläuft, und wenn das Scrollen stoppt, sollte der Kreis in der Mitte des nächstgelegenen Gehäuses bleiben
In meinem Beispiel passiert jetzt Folgendes: Wenn Sie mit dem Scrollen aufhören, bleibt es dort, wo es sein muss, aber bei mir scrollt es nicht richtig bis zum Ende
const circle = document.querySelector(".circle"); const cases = document.querySelectorAll(".case"); let timer = null; const detectCase = () => { const circleCenter = circle.offsetTop + circle.offsetHeight / 2; let activeCase = null, minDist = Infinity; cases.forEach((elem) => { const caseCenter = elem.offsetTop + elem.offsetHeight / 2; const dist = Math.abs(caseCenter - circleCenter); if (dist < minDist) { minDist = dist; activeCase = elem; } }); return activeCase; }; const handleScroll = () => { const { height: blockHeight } = document.querySelector(".block2").getBoundingClientRect(); const maxTop = cases[cases.length - 1].offsetTop; const minTop = cases[0].offsetTop; let { height: startTop } = cases[0].getBoundingClientRect(); let scrollDist = startTop / 2 + window.scrollY; scrollDist = scrollDist > maxTop ? maxTop : scrollDist < minTop ? minTop : scrollDist; circle.style.top = `${scrollDist}px`; circle.style.backgroundSize = `15px ${blockHeight}px`; circle.style.backgroundPosition = `0 ${-scrollDist}px`; if (timer) return; timer = setTimeout(() => { const active = detectCase(); const activePos = active.offsetTop + active.offsetHeight / 2; circle.style.top = `${activePos}px`; circle.style.backgroundPosition = `0 ${-activePos}px`; circle.style.transition = "0.5s"; timer = null; }, 800); circle.style.transition = ""; }; const handleWindowSize = () => { if (window.innerWidth >= 991) { window.addEventListener("scroll", handleScroll); window.addEventListener("resize", handleScroll); } else { window.removeEventListener("scroll", handleScroll); window.removeEventListener("resize", handleScroll); } }; handleScroll(); handleWindowSize(); window.addEventListener("resize", handleWindowSize);
.block1 { height: 200px; background-color: gray; } .block3 { height: 600px; background-color: gray; } .block2 { height: 100%; position: relative; } .block2, .block2 .circle { background: linear-gradient(214deg, rgba(79, 142, 255, 0) 0%, #4f8eff 10%, #f5e550 90%, rgba(79, 142, 255, 0) 100%) center/3px calc(100% - 100px) no-repeat; } .block2 .circle { width: 15px; height: 15px; left: calc(50% - 8px); } .block2 .circle, .block2 .circle::before { position: absolute; border-radius: 50%; } .block2 .circle::before { content: ""; inset: 3px; background-color: white; } .text { text-align: center; padding: 200px 50px; }
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" integrity="sha512-t4GWSVZO1eC8BM339Xd7Uphw5s17a86tIZIj8qRxhnKub6WoyhnrxeCIMeAqBPgdZGlCcG2PrZjMc+Wr78+5Xg==" crossorigin="anonymous" referrerpolicy="no-referrer" /> <div class="block1"></div> <div class="block2"> <div class="circle"></div> <div class="case"> <div class="row"> <div class="col-5 text">Text 1</div> <div class="col-2"></div> <div class="col-5 text">Text 1</div> </div> </div> <div class="case"> <div class="row"> <div class="col-5 text">Text 2</div> <div class="col-2"></div> <div class="col-5 text">Text 2</div> </div> </div> <div class="case"> <div class="row"> <div class="col-5 text">Text 3</div> <div class="col-2"></div> <div class="col-5 text">Text 3</div> </div> </div> </div> <div class="block3"></div>
如果我正确理解您的问题,我认为您可以将最后一个案例的半高添加到
maxTop
计算中,如下所示:这样,圆的最大顶部位置将位于最后一个案例的中间。请检查更新的代码片段: