Smooth Scroll in jQuery

JavaScript Complete solutions Smooth Scroll in jQuery

I've decided to write a series on jQuery - practical usage after being frequently asked about different jQuery utilities. We won't be learning jQuery, or JS, here, we'll just look at effective ways to save time and shorten our code.

Smooth scroll

Smooth scroll is probably the most used functionality on modern websites, particularly single page websites. The key principle of it is continuous changing of the screen position after clicking on some button, usually in the menu.

A lot of people writes long and ineffective code (meaning a lot of code with poor results). However, this functionality can be basically written on 3 lines.

As always, we'll write the code between

$(function() {

  // code...

});

Okay, the initialization is done. Prepare some sample website with a navigation menu and other texts with headings, which we're going to scroll through. I divided the page into 3 colored parts and added links to them in the menu. Every part is placed in a <div> with a corresponding id which is used in the menu links. The code in <body> without the long texts could look like this.

<body>

        <nav id="menu">
                <ul>
                        <li><a href="#red" class="button"><span>RED</span></a></li>
                        <li><a href="#green" class="button"><span>GREEN</span></a></li>
                        <li><a href="#blue" class="button"><span>BLUE</span></a></li>
                        <li id="ictsocial"><span>ICT.social</span></li>
                </ul>
        </nav>

        <div id="red">
                ...long text...
        </div>
        <div id="green">
                ...long text...
        </div>
        <div id="blue">
                ...long text...
        </div>

</body>

The result:

Your page
localhost

How to start? You have surely noticed that we need to handle the click event of our buttons. The buttons has to have both the href attribute, to determine where should the page scroll to, and a class to limit it only to specific buttons.

<a href="#red" class="button">RED</a>

For selecting our buttons, we'll use

$('a.button')

We'll assign the click event to it.

$('a.button').on('click', function() {

});

Into this anonymous function we're going to write the rest of our script. The first thing we should do is to determine our target to scroll the page to.

var target = $(this).attr('href');

If we use a fixed menu, which is widely used on single page websites, it's necessary to select it as well.

var menu = $('#menu');

Finally, we have to define the animation speed as well. The speed is always defined in milliseconds.

var speed = 2 * 1000;

The settings part should be done now. Now it's the animation time. We'll use the animate() function in which we'll animate scrollTop to our target's position. We'll get the target's position from $(target).offset().top and subtract the menu height from it, of course only if the menu is fixed.

But what we should animate? It's going to be <body> and <html>.

$("html, body").animate(
        { scrollTop: $(target).offset().top - menu.height() },
        speed, effect
);

The basis should be done now. Finally, we should also prevent showing our destination in the URL address. That can be done simply. Oh, and also add the e parameter to the anonymous function so we could prevent the default browser action which is following the link. We've taken the responsibility for this action.

e.preventDefault();

If we now test our code, we can notice that when clicking fast, for example on 10 menu items, the screen is jumping all over the place. It's because after clicking the button, an animation is started and when another button is clicked, another animation is queued but the previous one is still running. This effect can be prevented byadding:

.stop();

This will stop the current animation and start the next one immediately. And we're done.

Pretty, isn't it? The whole script looks like this:

$('a.button').on('click', function(e) {
        let link = $(this).attr('href');
        let menu = $('#menu');
        let speed = 2 * 1000;

        $("html, body").stop().animate(
                { scrollTop: $(link).offset().top - menu.height() },
        speed);

        e.preventDefault();
});

The code, of course, could be shortened even more, we could omit the settings for example. But I think this is good enough. The finished website can be downloaded below.


 

Download

Downloaded 1x (8.21 kB)
Application includes source codes in language JavaScript

 

 

Article has been written for you by Honza Bittner
Avatar
Do you like this article?
No one has rated this quite yet, be the first one!
Everything is possible.
Thumbnail
All articles in this section
Complete solutions in JavaScript
Activities (2)

 

 

Comments

To maintain the quality of discussion, we only allow registered members to comment. Sign in. If you're new, Sign up, it's free.

No one has commented yet - be the first!