I'm using Bootstrap v4.0.0
I have included the necessary JavaScript files (jQuery, popper and Bootstrap) and the necessary CSS files as well.
This is the HTML:
<body data-spy="scroll" data-target="#my-navbar-collapse" data-offset="100">
<!-- ... -->
<div class="collapse navbar-collapse" id="my-navbar-collapse">
<ul class="nav navbar-nav" role="tablist">
<li class="nav-item">
<a class="nav-link" href="#one">One</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#two">Two</a>
</li>
</ul>
</div>
<!-- ... -->
<section id="one">
Content.
</section>
<!-- ... -->
<section id="two">
More content.
</section>
<!-- ... -->
<script>
$(function() {
// As per the official docs:
// https://getbootstrap.com/docs/4.0/components/scrollspy/#events
$('[data-spy="scroll"]').on('activate.bs.scrollspy', function() {
console.log("This event is not firing...");
});
});
</script>
</body>
The menu items get highlighted properly when scrolling, but the JavaScript event activate.bs.scrollspy
is not firing.
I also tried to hook the event to the navbar
itself, but it does not fire either:
$('#my-navbar-collapse').on('activate.bs.scrollspy', function () {
console.log("Not firing either...");
})
I used to use this code with Bootstrap 3 and worked just fine.
Any thoughts?
Thank you.
Scrollspy works according to the scroll position or the position at which the user is currently is seeing. Bootstrap scrollspy targets the navigation bar contents automatically on scrolling the area.
The Scrollspy plugin is used to automatically update links in a navigation list based on scroll position.
To create a scrollspy, use the data-bs-spy=” scroll” attribute to make the required area scrollable. For example, we choose html body as the scrollable area. Give ID or class name of the navigation bar to data-bs-target attribute to connect navbar or list-group with scrollable area.
For some reason explained here, when you use body
for the spy element the event gets activated on the window
.
$(window).on('activate.bs.scrollspy', function () {
console.log("This event is not firing...");
});
Demo: https://www.codeply.com/go/aN4tfy0zU0
EDIT
The target element can be obtained in the 2nd event param:
$(window).on('activate.bs.scrollspy', function (e,obj) {
console.log(obj.relatedTarget);
});
@kim gave the right answer, but I also needed to hook to a scroll-end event, which does not seem to exist - so created something simple using a timeout:
// reset scroll watcher ##
clearTimeout( jQuery.data(this, 'scrollTimer'));
jQuery(window).on('activate.bs.scrollspy', function ( e,obj ) {
// console.log(obj.relatedTarget);
jQuery.data( this, 'scrollTimer', setTimeout(function() {
// console.log("Didn't scroll in 1/4 sec..");
// no scroll items are marked as active ##
if ( ! jQuery(".scrollspy-item.active")[0]){
// console.log("Can't fund any active scrollspy items..");
// add class to parent again ##
jQuery(".list-group-item.current").addClass( 'active' );
}
}, 250 ) );
});
In this case, I'm checking if any "scrollspy-items" are marked as active, or not and then adding the active class to a parent item, as we use the scrollspy in place in a sidebar menu.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With