滚动触发侧边栏上滑效果实现技术求助
Hey there! Let's figure out how to get that sidebar quote slide-up effect working, just like the site you mentioned. First off, this kind of interaction is called scroll-triggered animation for fixed elements—now you’ve got a keyword to search for if you want to dig deeper later.
Here’s a step-by-step breakdown of how to implement it:
1. Calculate the Trigger Point
First, you need to know when the user has scrolled past the first two articles. There are two reliable ways to do this:
Option 1: Sum the height of the first two articles
Grab the total height of the first two articles (including any margins/padding if they affect the scroll distance) to set your threshold:const article1 = document.querySelector('.main article:nth-child(1)'); const article2 = document.querySelector('.main article:nth-child(2)'); const triggerThreshold = article1.offsetHeight + article2.offsetHeight;Option 2: Detect when the second article leaves the viewport
UsinggetBoundingClientRect()is more precise because it accounts for the viewport height. We’ll check when the bottom of the second article is no longer visible:const article2 = document.querySelector('.main article:nth-child(2)'); const article2Rect = article2.getBoundingClientRect(); const hasScrolledPast = article2Rect.bottom < 0;
2. Listen for Scroll & Trigger the Animation
Since your sidebar is position: fixed, it doesn’t scroll with the main content—so we’ll listen to the window’s scroll event, check our trigger condition, and toggle a class on the quote element. Pro tip: Use requestAnimationFrame to throttle the event and avoid performance lag.
let isTicking = false; function handleScroll() { const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; const quote = document.querySelector('.sidebar .quote'); const article2Rect = article2.getBoundingClientRect(); // Pick either condition from step 1 const shouldAnimate = scrollTop >= triggerThreshold; // OR const shouldAnimate = article2Rect.bottom < 0; if (shouldAnimate) { quote.classList.add('slide-up'); } else { quote.classList.remove('slide-up'); } isTicking = false; } window.addEventListener('scroll', () => { if (!isTicking) { window.requestAnimationFrame(handleScroll); isTicking = true; } });
3. Add the CSS Animation
Use CSS transitions (or keyframes, if you want more complex movement) to make the quote slide up. Stick with transform for better performance (it doesn’t trigger layout reflows):
.sidebar .quote { position: fixed; /* Your default sidebar quote styles here */ transform: translateY(0); /* Starting position */ transition: transform 0.5s ease-out; /* Smooth transition */ } .sidebar .quote.slide-up { transform: translateY(-60px); /* Adjust this value for how far you want it to slide */ }
4. Bonus: Use Intersection Observer (Modern Approach)
If you want a more efficient way (no scroll event listening!), use the Intersection Observer API. It lets the browser tell you when an element enters or leaves the viewport:
const observer = new IntersectionObserver((entries) => { const quote = document.querySelector('.sidebar .quote'); const [entry] = entries; // When the second article is completely out of view if (!entry.isIntersecting) { quote.classList.add('slide-up'); } else { quote.classList.remove('slide-up'); } }, { threshold: 0 }); // Threshold 0 means trigger when 0% of the element is visible observer.observe(document.querySelector('.main article:nth-child(2)'));
This approach is cleaner and better for performance, especially on mobile.
Just a quick note: If your articles load dynamically (e.g., fetched from an API), make sure you run the threshold calculation or observer setup after the content has loaded—otherwise, the DOM elements won’t exist yet!
内容的提问来源于stack exchange,提问作者user3943543

