You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

实现.npp容器跟随#content滚动 对应章节同步置顶需求

Synchronized Scrolling Between Content and Fixed Sidebar

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 class attributes (you have <div class="canto" id="1uno" class="1uno">—merge these into one class attribute)
  • 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-1uno instead of 1uno)—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>

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

  1. Initial Setup: We grab references to your content container, sidebar, content sections, and sidebar links.
  2. 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.
  3. 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

火山引擎 最新活动