滚动时导航高亮及滚动加载项目的 Portfolio 网站开发求助
Hey there! Let's break down how to implement those two key features for your long-scroll portfolio—they'll make your site feel polished and performant.
1. Highlight Navigation Links When Scrolling to Corresponding Projects
The best way to handle this smoothly (without jank) is using the Intersection Observer API—it's way more efficient than listening to scroll events directly. Here's how to set it up:
Step 1: Basic HTML Structure
Make sure your navigation links point to the id of each project section:
<nav class="navbar"> <a href="#project1" class="nav-link">Project 1</a> <a href="#project2" class="nav-link">Project 2</a> <a href="#project3" class="nav-link">Project 3</a> </nav> <section id="project1" class="project-section">...</section> <section id="project2" class="project-section">...</section> <section id="project3" class="project-section">...</section>
Step 2: CSS for Highlight State
Define your default (gray) and active (blue) styles:
.nav-link { color: #888; /* Default gray */ transition: color 0.3s ease; } .nav-link.active { color: #007bff; /* Active blue */ }
Step 3: JavaScript with Intersection Observer
This will watch each project section and update the navigation when it enters the viewport:
// Get all project sections and navigation links const sections = document.querySelectorAll('.project-section'); const navLinks = document.querySelectorAll('.nav-link'); // Set up the observer const observerOptions = { root: null, // Use the viewport as the root rootMargin: '-20% 0px -70% 0px', // Trigger when section is 20% from top threshold: 0.1 }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { // Get the section's id const sectionId = entry.target.getAttribute('id'); // Remove active class from all links navLinks.forEach(link => link.classList.remove('active')); // Add active class to the corresponding link const activeLink = document.querySelector(`.nav-link[href="#${sectionId}"]`); if (activeLink) activeLink.classList.add('active'); } }); }, observerOptions); // Observe each section sections.forEach(section => observer.observe(section));
Adjust the rootMargin values to tweak when the highlight triggers—this setup starts highlighting when the section is 20% from the top of the viewport, which feels natural for most scroll experiences.
2. Hide Projects Until They Scroll Into View
Again, Intersection Observer is perfect here. We'll hide projects by default and reveal them when they enter the viewport (with a nice fade-in animation for extra flair):
Step 1: CSS for Hidden/Revealed States
.project-section { opacity: 0; transform: translateY(20px); /* Optional: slide up when revealing */ transition: opacity 0.6s ease, transform 0.6s ease; } .project-section.revealed { opacity: 1; transform: translateY(0); }
Step 2: Update the Intersection Observer
Modify the observer we created earlier to handle the reveal, or set up a separate one (I'll combine them for simplicity):
const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { // Reveal the section entry.target.classList.add('revealed'); // ... keep the navigation highlight code from earlier here const sectionId = entry.target.getAttribute('id'); navLinks.forEach(link => link.classList.remove('active')); const activeLink = document.querySelector(`.nav-link[href="#${sectionId}"]`); if (activeLink) activeLink.classList.add('active'); // Optional: Stop observing once revealed to save resources observer.unobserve(entry.target); } }); }, observerOptions);
Now your projects will stay hidden (with opacity 0) until they scroll into the viewport, then smoothly fade in. The transform adds a subtle slide-up effect, but you can remove that if you prefer a simple fade.
Quick Notes
- If you need to support older browsers (like IE11), you'll need a polyfill for Intersection Observer—you can find one on npm or CDNs.
- Test the
rootMarginvalues on different screen sizes to make sure the highlight and reveal triggers feel right for your layout.
Hope this gets your portfolio site working exactly how you want it!
内容的提问来源于stack exchange,提问作者EmmaKing

