Saya ada 3 blok, blok kedua ada garisan dan bulatan bergolek. Bulatan akan menatal dengan skrol utama, dan apabila menatal berhenti, bulatan akan melekat pada titik terdekat, iaitu pusat setiap blok
Tetapi saya mempunyai masalah ini di sini, apabila skrol utama melintasi blok kedua, bulatan berhenti menatal dan berkelakuan tidak betul pada halaman
Adakah mungkin untuk melengkapkan skrip supaya apabila skrol utama melintasi block2
时,圆圈将自动坚持最后一个案例并完全停止滚动?当我们返回并穿过 block2
, sewajarnya, ia akan berfungsi semula
Secara amnya masalahnya ialah kes terakhir, apabila skrol mencapainya, bulatan tidak bergerak lebih jauh, mungkin ada penyelesaian lain daripada pilihan yang saya cadangkan
Saya memerlukan tatal dari block2
mula hingga akhir agar lancar dan apabila tatal berhenti, bulatan harus melekat pada tengah kes terdekat
Dalam contoh saya inilah yang berlaku sekarang, jika anda berhenti menatal maka ia kekal di tempat yang sepatutnya, tetapi bagi saya ia tidak menatal dengan betul hingga akhir
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>
Jika saya memahami soalan anda dengan betul, saya rasa anda boleh menambah separuh ketinggian kes terakhir pada
maxTop
pengiraan seperti ini:Dengan cara ini, kedudukan teratas maksimum bulatan akan berada di tengah-tengah kes terakhir. Sila semak coretan kod yang dikemas kini: