Nate's previous & next stepper

HTML

<div class="nav">
    <button class="previous">Previous</button>
    <button class="next">Next</button>
</div>
<div class="steps"></div>

<h3>Separate links</h3>
<ul>
    <li><a href="#4">Go to four</a></li>
    <li><a href="#1">Go to one</a></li>
</ul>

CSS

body {
    font-family: sans-serif;
}

.nav {
    background-color: hsl(210, 50%, 50%);
    left: 0;
    padding: 10px;
    position: fixed;
    right: 0;
    top: 0;
}

.step {
    border: 1px solid #ccc;
    margin: 5px;
    padding: 10px;
}

.current {
    background: hsla(210, 50%, 50%, 0.1);
    border: 1px solid hsl(210, 50%, 50%);
}

JavaScript

var $win = $(window);
var $body = $('body');
var $nav = $('.nav');
var $previous = $nav.find('.previous');
var $next = $nav.find('.next');
var $steps = $('.steps');

// Set enough padding on the top to push the content below the fixed nav
$body.css('padding-top', $nav.outerHeight());

// Create some steps
for (var i = 0, length = 20; i < length; i += 1) {
    var $step = $('<div>', {
        id: i + 1,
        'class': 'step',
        text: 'I am step ' + (i + 1)
    });
    
    $step.appendTo($steps);
}

// Set the initial current step
var current = 1;
$('#' + current).addClass('current');

// Save the window position
var windowPosition = $win.scrollTop();

// Tell the next button what to do
$next.on('click', function (event) {
    current += 1;
    
    // Make sure you can't go past the last step
    if (current > 20) {
        current = 20;
    }
    
    // Set the hash (#whatever) to the current step
    window.location.hash = current;
});

$previous.on('click', function (event) {
    current -= 1;
    
    // Make sure you can't go past the first step
    if (current < 1) {
        current = 1;
    }
    
    // Set the hash (#whatever) to the current step
    window.location.hash = current;
});

// Create an event listener to handle hash changes
$win.on('hashchange', function (event) {
    
    // Reset the window position - by default it will jump
    // to the link. We want to hop back so fast it can't be seen
    $win.scrollTop(windowPosition);
    
    var $target = $(window.location.hash);
    var targetPosition = $target.offset().top;
    var navHeight = $nav.outerHeight();
    
    var margin = parseInt($target.css('margin-top'), 10);
    
    // The new window position is the target minus space for the
    // margin and for the fixed nav bar
    windowPosition = targetPosition - margin - navHeight;

    $('html,body').animate({
        scrollTop: windowPosition
    }, {
        duration: 'fast'
    });
    
   ...