实现.npp容器跟随#content滚动 对应章节同步置顶需求
Absolutely! You can pull off this synchronized scrolling effect where your fixed .npp sidebar follows the scroll position of your #content container—when a specific section in #content hits the top, its corresponding link in .npp will also align to the top of the sidebar. Let's break down the solution step by step, adjusted to fit your existing code:
First, Fix Minor HTML Issues
Before we jump into the script, let's clean up a couple of invalid HTML bits in your code:
- Elements can't have duplicate
classattributes (you have<div class="canto" id="1uno" class="1uno">—merge these into oneclassattribute) - While modern browsers tolerate class names starting with numbers, it's technically invalid CSS syntax. For better compatibility, I'll adjust class names to start with a letter (e.g.,
canto-1unoinstead of1uno)—feel free to keep your original names if you prefer, just tweak the script accordingly.
Here's the cleaned-up HTML snippet:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="npp"> <div class="in"> <a href="#canto-1uno">1</a> <a href="#canto-1due">2</a> <a href="#canto-1tre">3</a> <a href="#canto-1quattro">4</a> <a href="#canto-1cinque">5</a> </div> </div> <div id="content"> <div class="poema"> <div class="canto canto-1uno" id="canto-1uno"> <div class="inf">Inferno</div> <h3>I</h3> </div> <!-- Rest of your content for canto 1 --> <div class="canto canto-1due" id="canto-1due"> <div class="inf">Inferno</div> <h3>II</h3> </div> <!-- Rest of your content for canto 2 --> </div> </div>
CSS Tweaks (Optional but Recommended)
Your existing CSS works fine, but adding a width to .npp will make the sidebar more usable:
#content { width: 70%; } .npp { position: fixed; right: 0; top: 0; text-align: center; font-size: 10vw; line-height: 1.5em; overflow: auto; height: 100vh; padding: 20px; box-sizing: border-box; width: 30%; /* Match content's 70% to fill the viewport */ } .in a { display: block; margin: 10px 0; /* Add spacing between links for clarity */ }
The Core jQuery Script
This script will handle the synchronized scrolling:
$(document).ready(function() { const $content = $('#content'); const $npp = $('.npp'); const $sections = $content.find('.canto'); const $links = $npp.find('a'); // Function to sync sidebar scroll with content function syncScroll() { const contentScrollTop = $content.scrollTop(); $sections.each(function(index) { const $section = $(this); const sectionTop = $section.offset().top - $content.offset().top; const sectionId = $section.attr('id'); const $correspondingLink = $links.filter(`[href="#${sectionId}"]`); // Check if this section is at or above the content's top if (sectionTop <= contentScrollTop) { // Calculate how much to scroll the sidebar to align the link to the top const linkOffsetTop = $correspondingLink.offset().top - $npp.offset().top; $npp.scrollTop(linkOffsetTop); } }); } // Run on initial load to set the first link in place syncScroll(); // Run every time the content is scrolled $content.on('scroll', syncScroll); });
How It Works
- Initial Setup: We grab references to your content container, sidebar, content sections, and sidebar links.
- Sync Function:
- On scroll, we check the current scroll position of
#content. - For each section in
#content, we calculate its relative position to the content container. - When a section reaches the top of
#content, we find its matching link in.npp. - We scroll the sidebar so that this link aligns perfectly with the top of
.npp.
- On scroll, we check the current scroll position of
- Initial Run: We trigger the sync function once on page load to ensure the first link is in the correct position.
Bonus: Smooth Scrolling (Optional)
If you want the sidebar scroll to be smooth instead of instant, replace the $npp.scrollTop(linkOffsetTop); line with:
$npp.animate({ scrollTop: linkOffsetTop }, 150);
This will make the transition feel more polished!
内容的提问来源于stack exchange,提问作者Federico




