This tutorial is out of date and no longer maintained.
Last week we put out a challenge to build out a scroll-spy navbar. Scroll-spy navbars are great and highlight the navbar menu when a specific element or portion of the page comes into view. Are you yet to take the challenge? Do so and showcase your submission in the comment section of the post or on Twitter using the hashtag #scotchchallenge
to receive reviews. This challenge can be completed using any language, tool, technique, or technology.
In this post, we shall be solving this challenge by implementing the scroll-spy on the provided base code using Vanilla JavaScript and in-view.js. This will be achieved in about 11 lines of code.
In-view.js is a JavaScript utility that notifies us when a DOM element enters or exits a viewport.
Base code was provided for this challenge which consisted of HTML and CSS code to deliver the base structure and style of the page.
In the HTML, a nav element is used to create the navbar and a section element houses the body of the page. The body contains headers of different sizes created with h1
and h2
elements. Bulma classes were used to style the various headers and the navbar.
While Bulma classes have been used to style the page, the padding-top
property of the body element is styled to accommodate the fixed navbar.
No JavaScript was included in the base code provided.
In-view.js provides a seamless way to handle elements when they enter and exit the viewport, most likely during scroll. Once we scroll to a section, the class list of the corresponding navbar menu is updated. Bulma provides an is-active
class which highlights a menu item when active. This class will be toggled on and off whenever a menu item enters or leaves the viewport respectively.
While in-view can be installed using the node.js package manager npm, we shall be importing the script from a CDN.
In the CodePen, add a new external script from here.
Using the on
method in in-view, we state actions that will be carried out when an element enters or exits the viewport. The on
method takes two parameters with the first being either enter
or exit
and the second is a callback function with an argument which is the element entering or leaving the viewport.
Also, it is necessary to minimize the viewport area being watched so, we don’t have two elements in the viewport at a time. This is achieved by specifying an offset of the viewport using the offset()
method.
Note: That in this demo, only the headers are tracked during scroll and subsequent use cases may require tracking the whole content of a section during scroll.
While registering these methods on a single DOM element, we would like to spy on all the headers of the menu items at once. This will be achieved using the forEach()
method to traverse the elements and apply an in-view function to each element. This is done with:
Once we created a function that takes an argument of the unique identifier in each DOM element, we apply the in-view method and used the forEach()
method to spread the function across the elements. Zero rocket science! Also, it can be seen that the viewport is offset by 60% from the bottom, this means that the header has to enter the top 40% of the page to be considered in view.
Here is the final product:
https://codepen.io/Chuloo/pen/vjWBmX?editors=1010
In this post, we successfully completed the challenge by implementing the scroll-spy on the navbar using in-view.js and an is-active
Bulma class to highlight the navbar. This is just a simple use case of in-view.js, feel free to try it out in other cool UI tricks and techniques while building awesome stuff. Feel free to leave your comments and feedback in the comment section and let’s watch out for the next challenge. Happy coding!!
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!