18

18Sticky navigation

18.3

Using the Waypoints plugin

The sticky navigation takes place on every web page within the website. The code to make this work is identical for every page too; the links within the navigation bar change for each page, but the operation of the sticky navigation is the same for all pages.

As such, the sticky navigation jQuery code is in the common script.js file (rather than the page specific scroll.js file.

At present, all the script.js file has in it is the basic jQuery code:

11-resources/05-js/script.js
$(document).ready(function() {                  /* START OF PAGE READY FUNCTION */

/* ****************************************************************************
   YOUR CODE GOES IN HERE
   **************************************************************************** */

});                                             /* END OF PAGE READY FUNCTION */
Code 18.2   script.js

The only thing we need to add is the Waypoints code. It looks like this:

11-resources/05-js/script.js
$(document).ready(function() {                  /* START OF PAGE READY FUNCTION */

    $('#js--fixed-nav').waypoint(function (direction) { /* START of Waypoint function
        if (direction == "down") {                      /* check direction */
            $('nav').addClass('fixed-nav');             /* if down add fixed-nav class */
        } else {
            $('nav').removeClass('fixed-nav');          /* if up clear fixed-nav class */
        }
    }, {
    offset: '70px'                                      /* check 70px before top */
    });                                                 /* END of Waypoint function */

});                                             /* END OF PAGE READY FUNCTION */
Code 18.3   Waypoints code

The Waypoints method can do a lot of different things, it is a powerful bit of code (I don’t understand most of it). I’m just using if to detect when a particular ID reaches the top of the browser window when I scroll down the page.

The ID I’m looking for is called js--fixed-nav (I haven’t added it to the HTML yet).

I’m using this ID as a jQuery selector that uses the Waypoints method:

$('#js--fixed-nav').waypoint(function (direction) {

The waypoint executes the function when the HTML ID js--fixed-nav passes the top of the browser window. It does this in both directions (I.e. scrolling up or down).

This time the function has a parameter (direction) that is populated by the Waypoint method. It gets the value down if the user is scrolling down the page when the ID passes the top of the browser window; it gets the value up if the user is scrolling up the page when the ID passes the top of the browser window

And that is all the Waypoints method does. It executes the function when the ID passes through the top of the browser window and tells us if the user is scrolling up or down.

The rest is up to us.

The next bit is a mixture of both JavaScript and jQuery. The first bit is an if else statement and that is JavaScript:

if (direction == "down") { }
else { }

It says if the value of the variable direction is equivalent to "down" then do what is between the braces (== means equivalent to). If the value of the variable direction is not equivalent to "down" then do what is in the braces following else.

It is a straight forward if else structure:

if (condition) {code to execute if condition is true}
else {code to execute if condition is false}

Thus, if we are scrolling down the page and the ID js--fixed-nav passes the top of the browser window we execute the following bit of code:

$('nav').addClass('fixed-nav')

This bit is jQuery and it demonstrates just how powerful and useful jQuery is with websites. This addClass method literally adds another class to a HTML element.

Our original <nav> element looked like this:

<nav>                             <!-- Start of top navigation bar -->
    <div class="top-nav">         <!-- Start of top navigation row -->
...

If the addClass bit of code were executed, it would do the same as:

<nav class="fixed-nav">           <!-- Start of top navigation bar -->
    <div class="top-nav">         <!-- Start of top navigation row -->
...

The syntax is:

$(target).addClass(new-class)

When executed, the target element gets the class new-class attached to it.

So in our case, when the user scrolls down the web page and passes the js--fixed-nav ID, the <nav> element effectively becomes <nav class="fixed-nav">.

Conversely, if the user is scrolling up the web page and passes the point, where the js--fixed-nav ID passes the top of the window, the if else gets executed again, this time direction has the value "up", so this time the condition is false and the code in the else braces executes and that does this:

$('nav').removeClass('fixed-nav')

Can you guess what it does?

Well bugger me, it only goes and takes that class off again.

The whole thing works like a switch, when we scroll down past the point, we add a class to the <nav> element, when we scroll up again past the same point it takes it off again.

It took me ages to get this right, and it’s very simple really — except when you are starting from scratch and don’t know what you are doing. It did make me smile once I’d figured it out. That smug self-satisfied, aren’t I clever, pat yourself on the back, sort of smile.

Yey Caleb Troughton.

There is one final thing, the offset:

offset: '70px'

This allows us to control exactly when the Waypoints method gets triggered, in this case it is 70 pixels before the ID reaches the top of the screen, this means that when the sticky nav appears, it doesn’t cover the text we’re targeting — it just makes it look right.



End flourish image