Kyle Banks

Detecting Scroll Events and Getting the Current Scroll Offset with jQuery

Written by @kylewbanks on Apr 20, 2013.

Update: August 10, 2016

Note: This post references a design of this site that is no longer applicable. Instead the code will now update the header background color and box-shadow instead. Here’s the updated source code:

var $header = $('.header'),
    scrollClass = 'on-scroll',
    activateAtY = 20;

function deactivateHeader() {
    if (!$header.hasClass(scrollClass)) {
        $header.addClass(scrollClass);
    }
}

function activateHeader() {
    if ($header.hasClass(scrollClass)) {
        $header.removeClass(scrollClass);
    }
}

$(window).scroll(function() {
    if($(window).scrollTop() > activateAtY) {
        deactivateHeader();
    } else {
        activateHeader();
    }
});

Original Post:

When I was working on redesigning the side-navigation for this site, I wanted to add some color to it without making it distracting while reading posts. I decided that the white background was great during reading because it lets the eye focus on the blog content, but visually it leaves something to be desired.

The solution I came up with is the grey background and slightly darker border you see now, giving the illusion that it’s in the background, almost behind the blog content. I love the look, but I still find it distracting while reading. So I know it needs to be less distracting while reading, but how do you determine if the user is reading? Well, they scroll.

Detecting Scroll Events

The first thing you have to do is detect when the user is scrolling the page. Because this event can potentially fire hundreds, if not thousands of times during a normal scroll, be careful not to do any heavy processing in it.

$(window).scroll(function() {
    // User is scrolling
});

The above code binds the scroll event to window, meaning it will fire any time the page scrolls. If you want, you can bind this event to any element that may scroll independently from window such as a textarea or a particular div.

Detecting the Scroll Offset

Once you know the user has scrolled you can detect whereabouts on the page they are. For the purpose of this blog, I needed to know whether or not they were at the top of the page.

$(window).scroll(function() {
    if($(window).scrollTop() > 0) {
        headerOff();
    } else {
        headerOn();
    }
});

Using the scrollTop method you can determine if they have scrolled down the page. You can see this in action by scrolling up and down this page. When you are at the top, the side-navigation (header) lights up. When you scroll down, it goes opaque. In addition to scrollTop, you can also make use of scrollBottom, scrollRight, and scrollLeft.

Notes

If you look through the JavaScript source code, you will notice that in the headerOn and headerOff methods I only do any DOM manipulation if the header isn’t already in the desired state (I do this by applying a CSS off class when the user scrolls down, and removing it when they reach the top). This significantly reduces the amount of processing required during scrolling, and is very important to maintain a smooth UX.

Another thing to note is that if your html and/or body element has a height: 100% style set, you’ll need to bind the scroll event to a particular element like so:

$('#content-container').scroll(function() {
    // Put logic here
});
Let me know if this post was helpful on Twitter @kylewbanks or down below!