Sticky定位div滚动时反复淡入淡出后停止,求JQuery代码修复方案
Hey there! Let's break down why your sticky .processor divs are flickering with fade-in/fade-out and eventually stopping, plus how to fix it.
The Core Problems in Your Current Code
- Overloaded Animation Queue: The
scrollevent fires constantly as the user scrolls. Every time it triggers, you're adding newfadeToanimations to each div's queue. After a while, the queue gets backed up and stops responding entirely. - Array Index Mismatch: You start
$counterat 1 when populatingfromTop, but JavaScript arrays are 0-indexed. This means your first div's offset gets stored infromTop[1]instead offromTop[0], and when you checkfromTop[$counter-1]in the first loop iteration, you're accessingfromTop[0]which is undefined. - Conflicting Logic: Your two
ifstatements can fire at the same time for the same div, telling it to fade out and fade in simultaneously—this causes the flickering effect.
Fixed Code & Explanations
First, let's clean up the scroll handling, fix the indexing, and add animation queue management:
// Initialize variables properly (0-indexed array) let fromTop = []; $('.processor').each(function(index) { fromTop[index] = $(this).offset().top; }); // Use a debounced scroll handler to reduce event frequency $(window).on('scroll', function() { $('.processor').each(function(index) { const scrollTop = $(window).scrollTop(); // Clear existing animation queue before adding new ones $(this).stop(true, true); // Simplified logic: Determine if the div should be visible or not if (scrollTop > fromTop[index]) { $(this).fadeTo(500, 0); } else { $(this).fadeTo(500, 1); } // If you need to handle the "previous div" logic, adjust it to avoid conflicts // Example: Only show if we're above the previous div's threshold if (index > 0 && scrollTop <= fromTop[index - 1]) { $(this).fadeTo(500, 1); } }); });
Key Fixes:
0-Indexed Array: We use the native
indexparameter from.each()to populatefromTopcorrectly, so no more undefined values.stop(true, true): This clears the div's animation queue and jumps to the end of any ongoing animation—preventing queue buildup and immediate response to scroll changes.Debounced Scroll (Optional but Recommended): If you want to further reduce scroll event triggers, you can wrap the scroll handler in a debounce function:
function debounce(func, delay) { let timeoutId; return function() { clearTimeout(timeoutId); timeoutId = setTimeout(func, delay); }; } $(window).on('scroll', debounce(function() { // Your scroll logic here }, 100));This delays the logic from running until the user stops scrolling for 100ms, reducing unnecessary animations.
Simplified Logic: We've adjusted the conditions to avoid conflicting fade commands. If you need the "previous div" visibility rule, make sure it only triggers when it doesn't clash with the main visibility condition.
CSS Check
Your CSS for .processor looks fine, but just a quick note: position: sticky relies on a parent container to define its scroll boundary. Make sure the parent element doesn't have overflow: hidden set, as that can break sticky positioning.
.processor{ width:65%; height:70%; background: linear-gradient(rgba(179, 0, 0, 0.75), rgba(95, 0, 0, 0.75)); margin: 0 auto; overflow:hidden; border-radius:3px; top: 18%; position:sticky; margin-bottom:250px; }
Give this adjusted code a try—your divs should fade smoothly without flickering or stopping unexpectedly!
内容的提问来源于stack exchange,提问作者Neyco

