实现逐面板滚动:固定后滚动及重叠区块依次滚动效果
Overlapping Section Scroll Sequencing Solution
Got it, let's build that sequential scroll effect where each section only starts moving once the previous one has fully exited the viewport. Here's a complete, performant implementation tailored to your needs:
Step 1: Refine the HTML Structure
First, wrap your sections in a container for better control, and add a shared class to target all scroll sections easily:
<div class="scroll-container"> <div id="section1" class="scroll-section"> <h2>Section 1 Content</h2> <p>Fill this with your actual content...</p> </div> <div id="section2" class="scroll-section"> <h2>Section 2 Content</h2> <p>Fill this with your actual content...</p> </div> </div>
Step 2: Update CSS for Overlap & Base Styling
We'll keep your existing overlap, but add some base styles to prevent layout issues and ensure smooth scrolling:
body { margin: 0; padding: 0; overflow-x: hidden; /* Prevent horizontal scroll from section movement */ } .scroll-container { position: relative; } .scroll-section { position: relative; height: 500px; padding: 2rem; box-sizing: border-box; /* Include padding in height calculation */ } #section1 { background-color: darkgray; } #section2 { background-color: pink; top: -200px; /* 200px overlap with section1 */ }
Step 3: JavaScript for Sequential Scroll Logic
This is the core part. We'll use a throttle function to optimize scroll performance, calculate trigger points for each section, and apply smooth GPU-accelerated movement with transform:
// Throttle function to limit scroll event frequency (prevents jank) function throttle(func, limit) { let inThrottle; return function() { const args = arguments; const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } } } // Get all scroll sections and define key values const sections = document.querySelectorAll('.scroll-section'); const sectionHeight = sections[0].offsetHeight; const overlapHeight = 200; const viewportHeight = window.innerHeight; // Calculate when each section should start moving const triggerPoints = []; sections.forEach((section, index) => { if (index === 0) { // First section starts moving once we've scrolled past the viewport height triggerPoints.push(viewportHeight); } else { // Subsequent sections trigger after the previous one has fully exited (minus overlap) triggerPoints.push(triggerPoints[index-1] + sectionHeight - overlapHeight); } }); // Handle scroll-based section movement function handleScroll() { const scrollY = window.scrollY; sections.forEach((section, index) => { let translateY = 0; if (index === 0) { // Move section1 upward until it's fully out of view if (scrollY >= triggerPoints[index]) { translateY = Math.min(-(scrollY - triggerPoints[index]), -sectionHeight); } } else { // Keep section2 fixed in overlap position until its trigger point if (scrollY >= triggerPoints[index]) { translateY = Math.min(-(scrollY - triggerPoints[index]), -sectionHeight); } else if (scrollY >= triggerPoints[index-1]) { translateY = -(sectionHeight - overlapHeight); } } // Use transform for smooth, GPU-accelerated movement section.style.transform = `translateY(${translateY}px)`; }); } // Attach throttled scroll listener (16ms = ~60fps) window.addEventListener('scroll', throttle(handleScroll, 16)); // Run initial check on page load to set correct positions handleScroll();
Key Notes:
- Throttling: Critical for performance—scroll events fire hundreds of times per second, so we limit execution to every 16ms to match screen refresh rate.
- GPU Acceleration: Using
transform: translateY()instead of adjustingtopensures smooth movement, as transform operations are handled by the GPU rather than triggering layout reflows. - Scalability: You can add more sections by simply adding new
<div class="scroll-section">elements—the JavaScript will automatically calculate trigger points for them.
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

