18

18Sticky navigation

18.3

Using the Waypoints plugin

The sticky nav­i­ga­tion takes place on every web page within the web­site. The code to make this work is iden­ti­cal for every page too; the links within the nav­i­ga­tion bar change for each page, but the op­er­a­tion of the sticky nav­i­ga­tion is the same for all pages.

As such, the sticky nav­i­ga­tion jQuery code is in the com­mon script.js file (rather than the page spe­cific scroll.js file.

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

11-resources/05-js/script.js
  1. $(document).ready(function() {                  /* START OF PAGE READY FUNCTION */
  2.  
  3. /* ****************************************************************************
  4.   YOUR CODE GOES IN HERE
  5.   **************************************************************************** */
  6.  
  7. });                                            /* END OF PAGE READY FUNCTION */
Code 18.2   script.js

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

11-resources/05-js/script.js
  1. $(document).ready(function() {                  /* START OF PAGE READY FUNCTION */
  2.  
  3.     $('#js--fixed-nav').waypoint(function (direction) { /* START of Waypoint function
  4.         if (direction == "down") {                      /* check direction */
  5.             $('nav').addClass('fixed-nav');            /* if down add fixed-nav class */
  6.         } else {
  7.             $('nav').removeClass('fixed-nav');          /* if up clear fixed-nav class */
  8.         }
  9.     }, {
  10.     offset: '70px'                                      /* check 70px before top */
  11.     });                                                /* END of Waypoint function */
  12.  
  13. });                                            /* END OF PAGE READY FUNCTION */
Code 18.3   Waypoints code

The Way­points method can do a lot of dif­fer­ent things, it is a pow­er­ful bit of code (I don’t un­der­stand most of it). I’m just using if to de­tect when a par­tic­u­lar ID reaches the top of the browser win­dow when I scroll down the page.

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

I’m using this ID as a jQuery se­lec­tor that uses the Way­points method:

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

The way­point ex­e­cutes the func­tion when the HTML ID js--fixed-nav passes the top of the browser win­dow. It does this in both di­rec­tions (I.e. scrolling up or down).

This time the func­tion has a pa­ra­me­ter (di­rec­tion) that is pop­u­lated by the Way­point method. It gets the value down if the user is scrolling down the page when the ID passes the top of the browser win­dow; it gets the value up if the user is scrolling up the page when the ID passes the top of the browser win­dow

And that is all the Way­points method does. It ex­e­cutes the func­tion when the ID passes through the top of the browser win­dow and tells us if the user is scrolling up or down.

The rest is up to us.

The next bit is a mix­ture of both JavaScript and jQuery. The first bit is an if else state­ment and that is JavaScript:

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

It says if the value of the vari­able di­rec­tion is equiv­a­lent to "down" then do what is be­tween the braces (== means equiv­a­lent to). If the value of the vari­able di­rec­tion is not equiv­a­lent to "down" then do what is in the braces fol­low­ing else.

It is a straight for­ward if else struc­ture:

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 win­dow we ex­e­cute the fol­low­ing bit of code:

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

This bit is jQuery and it demon­strates just how pow­er­ful and use­ful jQuery is with web­sites. This ad­d­Class method lit­er­ally adds an­other class to a HTML el­e­ment.

Our orig­i­nal <nav> el­e­ment looked like this:

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

If the ad­d­Class bit of code were ex­e­cuted, 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 syn­tax is:

$(target).addClass(new-class)

When ex­e­cuted, the tar­get el­e­ment gets the class new-class at­tached to it.

So in our case, when the user scrolls down the web page and passes the js--fixed-nav ID, the <nav> el­e­ment ef­fec­tively be­comes <nav class="fixed-nav">.

Con­versely, if the user is scrolling up the web page and passes the point, where the js--fixed-nav ID passes the top of the win­dow, the if else gets ex­e­cuted again, this time di­rec­tion has the value "up", so this time the con­di­tion is false and the code in the else braces ex­e­cutes and that does this:

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

Can you guess what it does?

Well bug­ger 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> el­e­ment, 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 sim­ple re­ally — ex­cept when you are start­ing from scratch and don’t know what you are doing. It did make me smile once I’d fig­ured it out. That smug self-sat­is­fied, aren’t I clever, pat your­self on the back, sort of smile.

Yey Caleb Troughton.

There is one final thing, the off­set:

offset: '70px'

This al­lows us to con­trol ex­actly when the Way­points method gets trig­gered, in this case it is 70 pix­els be­fore the ID reaches the top of the screen, this means that when the sticky nav ap­pears, it doesn’t cover the text we’re tar­get­ing — it just makes it look right.



End flourish image