如何在Rails中使用Bootstrap4 Scrollspy(无需<body>标签)
Let's walk through fixing both your issues: the page reloading when clicking anchor links, and the navigation not highlighting on scroll. Here's a complete, working example tailored for Rails:
Working Code Example
<!-- Add Bootstrap 4 CSS (via asset pipeline or CDN) --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> <div class="row"> <div class="col-12"> <!-- Navigation --> <nav id="navbar-orders-now-status" class="navbar navbar-light bg-light"> <ul class="nav nav-pills"> <li class="nav-item"> <!-- Add data-turbolinks="false" to prevent Rails from reloading the page --> <a class="nav-link scroll-link" href="#SECTION1" data-turbolinks="false">SECTION1</a> </li> <li class="nav-item"> <a class="nav-link scroll-link" href="#SECTION2" data-turbolinks="false">SECTION2</a> </li> <li class="nav-item"> <a class="nav-link scroll-link" href="#SECTION3" data-turbolinks="false">SECTION3</a> </li> </ul> </nav> <!-- Scroll Container: Added position: relative (required by Bootstrap Scrollspy) --> <div class="row scroll-container" data-spy="scroll" data-target="#navbar-orders-now-status" data-offset="0" style="height: 300px; overflow-y: scroll; position: relative;"> <div class="col-12"> <h4 id="SECTION1">SECTION1</h4> <table class="table table-sm"> <tbody> <!-- Add dummy content to make sections scrollable --> <% 20.times do %> <tr><td>Dummy Row <%= rand(100) %></td></tr> <% end %> </tbody> </table> <h4 id="SECTION2">SECTION2</h4> <table class="table table-sm"> <tbody> <% 20.times do %> <tr><td>Dummy Row <%= rand(100) %></td></tr> <% end %> </tbody> </table> <h4 id="SECTION3">SECTION3</h4> <table class="table table-sm"> <tbody> <% 20.times do %> <tr><td>Dummy Row <%= rand(100) %></td></tr> <% end %> </tbody> </table> </div> </div> </div> </div> <!-- Add jQuery and Bootstrap 4 JS (required for Scrollspy) --> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script> <script> // Initialize Scrollspy manually (more reliable in Rails/Turbo environments) $(document).ready(function() { $('.scroll-container').scrollspy({ target: '#navbar-orders-now-status', offset: 0 }); // Handle anchor clicks to scroll smoothly without page reload $('.scroll-link').on('click', function(e) { e.preventDefault(); // Stop Rails from triggering a page reload const targetId = $(this).attr('href'); // Scroll to the target section inside the scroll container $('.scroll-container').animate({ scrollTop: $(targetId).offset().top - $('.scroll-container').offset().top + $('.scroll-container').scrollTop() }, 300); }); }); // If using Turbo/Rails 7+, re-initialize Scrollspy after page loads document.addEventListener('turbo:load', function() { $('.scroll-container').scrollspy('refresh'); }); </script>
Key Fixes Explained
1. Stop Page Reload on Anchor Clicks
Rails (especially with Turbo/Turbolinks) treats anchor links as full page requests by default. We fix this by:
- Adding
data-turbolinks="false"to each anchor link to disable Turbo's default behavior - Using JavaScript to prevent the default click action and handle smooth scrolling manually
2. Fix Scrollspy Highlighting
Bootstrap Scrollspy requires the scroll container to have position: relative (we added this inline to the scroll container). Without this, Scrollspy can't correctly calculate the scroll position to update active navigation links.
We also initialize Scrollspy manually instead of relying solely on data attributes—this is more reliable in Rails dynamic environments where the DOM might load asynchronously.
3. Handle Turbo/Rails 7+ Compatibility
If you're using Rails 7+ with Turbo, we added a turbo:load event listener to refresh Scrollspy after the page loads. This ensures the plugin works correctly when Turbo replaces parts of the DOM.
内容的提问来源于stack exchange,提问作者Sven Kirsten

