我有 3 個區塊,第二個區塊有一條線和一個滾動圓。圓圈會隨著主滾動一起滾動,當滾動停止時,圓圈會粘到最近的點,即每個塊的中心
但是我在這裡遇到這樣的問題,當主滾動穿過第二個區塊時,圓圈停止滾動並且在頁面上表現不正確
是否可以完成腳本,以便當主滾動穿過 block2
時,圓圈將自動堅持最後一個案例並完全停止滾動?當我們返回並穿過 block2
時,相應地,它應該再次工作
一般來說,問題在於最後一種情況,當滾動到達它時,圓圈不會進一步移動,也許還有另一種解決方案,而不是我建議的選項
我需要從block2
開始到結束的滾動是平滑的,並且當滾動停止時,圓圈應該粘在最近的案例的中心
在我的範例中,這就是現在發生的情況,如果您停止滾動,那麼它會停留在需要的位置,但對我來說它不會正確滾動到末尾
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
計算中,如下所示:這樣,圓的最大頂部位置將位於最後一個案例的中間。請檢查更新的程式碼片段: