纯JavaScript实现Div内图片随滚动切换的方法求助
Hi there! Let's get that scroll-triggered image switch effect working just like the site you're referencing—pure JavaScript, no libraries needed. First, let's fix the small issues in your current code, then build out the full solution with page scroll locking until all images are done switching.
Issues in Your Current Code
- Typo:
getElemebtByIdshould begetElementById(missing an 'n') - Visibility vs Display:
visibility: hiddenkeeps the element's space in the layout, which can cause weird jumps. We'll usedisplay: nonewith anactiveclass instead for clean transitions. - Wrong Scroll Listener: You're listening to the window scroll, but you want the trigger to happen when scrolling inside your image container.
- No Scroll Lock: Your code doesn't handle locking the page scroll until all image switches are complete.
Full Working Solution
Here's a polished implementation that hits all your requirements:
HTML
We'll structure the images in a container that's scrollable, with extra page content to test the scroll lock:
<div class="page-content"> <!-- Dummy content to make the page scrollable --> <p>Scroll down to reach the image container...</p> <p>Scroll down to reach the image container...</p> <p>Scroll down to reach the image container...</p> <p>Scroll down to reach the image container...</p> <p>Scroll down to reach the image container...</p> <div class="image-container-wrapper"> <div class="image-container" id="imageContainer"> <div class="image-item active"> <img src="IMAGES/sunglasses.jpeg" alt="Woman with Sunglasses"> </div> <div class="image-item"> <img src="IMAGES/dancer1.jpg" alt="A Dancer"> </div> <div class="image-item"> <img src="IMAGES/third-image.jpg" alt="Third Image"> </div> </div> </div> <!-- More dummy content below --> <p>You'll only see this after all images are switched!</p> <p>You'll only see this after all images are switched!</p> </div>
CSS
We'll style the container to be fixed-height, hide scrollbars (optional), and add a class to lock page scroll:
/* Base page styles */ .page-content { min-height: 2000px; /* Ensure the page has enough scroll space */ padding: 2rem; } /* Wrapper to contain the scrollable image container */ .image-container-wrapper { max-width: 50%; height: 60vh; /* Adjust height to fit your design */ overflow: hidden; position: relative; margin: 2rem 0; } /* Scrollable container for images */ .image-container { height: 100%; overflow-y: auto; /* Hide scrollbar for cleaner look (optional) */ scrollbar-width: none; } .image-container::-webkit-scrollbar { display: none; } /* Image items - hidden by default, active shows them */ .image-item { height: 100%; display: none; align-items: center; justify-content: center; } .image-item.active { display: flex; } .image-item img { max-width: 100%; max-height: 100%; object-fit: cover; /* Keep image aspect ratio */ } /* Class to lock page scroll */ body.scroll-locked { overflow: hidden; height: 100vh; }
JavaScript
This handles the scroll trigger, image switching, and page scroll locking:
// Grab elements from the DOM const imageContainer = document.getElementById('imageContainer'); const imageItems = document.querySelectorAll('.image-item'); const body = document.body; // Track state let currentImageIndex = 0; const totalImages = imageItems.length; const scrollThreshold = 0.8; // Switch when 80% scrolled let isSwitching = false; // Prevent duplicate triggers // Initialize: show first image imageItems[currentImageIndex].classList.add('active'); // Listen for scroll inside the image container imageContainer.addEventListener('scroll', () => { if (isSwitching) return; // Skip if we're already switching images // Calculate how far we've scrolled (as a ratio) const scrollRatio = imageContainer.scrollTop / (imageContainer.scrollHeight - imageContainer.clientHeight); // Switch to next image if we hit the threshold and aren't on the last image if (scrollRatio > scrollThreshold && currentImageIndex < totalImages - 1) { switchToNextImage(); } }); // Handle switching to the next image function switchToNextImage() { isSwitching = true; body.classList.add('scroll-locked'); // Lock page scroll // Hide current image, show next imageItems[currentImageIndex].classList.remove('active'); currentImageIndex++; imageItems[currentImageIndex].classList.add('active'); // Reset container scroll to top for next scroll trigger imageContainer.scrollTop = 0; // Unlock page scroll if we're on the last image if (currentImageIndex === totalImages - 1) { setTimeout(() => { body.classList.remove('scroll-locked'); isSwitching = false; }, 500); // Small delay for smoothness } else { setTimeout(() => { isSwitching = false; }, 300); } } // Optional: Add back navigation by scrolling up to top imageContainer.addEventListener('scroll', () => { if (isSwitching) return; if (imageContainer.scrollTop === 0 && currentImageIndex > 0) { switchToPreviousImage(); } }); function switchToPreviousImage() { isSwitching = true; imageItems[currentImageIndex].classList.remove('active'); currentImageIndex--; imageItems[currentImageIndex].classList.add('active'); // Scroll container to bottom for next up-scroll trigger imageContainer.scrollTop = imageContainer.scrollHeight - imageContainer.clientHeight; setTimeout(() => { isSwitching = false; }, 300); }
Key Features Explained
- Responsive Scroll Trigger: Uses a scroll ratio instead of fixed pixels, so it works on all screen sizes.
- Page Scroll Lock: Adds a class to
bodyto prevent scrolling until all images are viewed. - Prevent Duplicate Triggers: The
isSwitchingflag stops the scroll event from firing multiple times during a transition. - Smooth Transitions: Small delays and scroll resets make the experience feel natural.
内容的提问来源于stack exchange,提问作者sGlow
相关产品推荐
相关产品推荐

