jQuery One Page Navigation Plugin

When appropriate, I am a fan of the one-page sites. I really like the ones that add smooth scrolling and highlight the navigation depending upon which part of the page you have scrolled to. Here are a few examples: Brizk Design and Crush + Lovely. I finally have a freelance project where a one-page site makes sense, so I needed to write the JavaScript to make the navigation work how I wanted.

I wanted the page to scroll smoothly when the navigation was clicked, so I used the jQuery ScrollTo plugin. I also wanted the page to automatically highlight the correct navigation section depending upon which section was scrolled to, and that was where I added my custom code.

If you want to skip ahead, you can check out the demo and download the plugin from GitHub.

The Markup

I started with an unordered list for the navigation and a bunch of sections:

<ul id="nav">
  <li class="current"><a href="#section-1">Section 1</a></li>
  <li><a href="#section-2">Section 2</a></li>
  <li"><a href="#section-3">Section 3</a></li>
</ul>

<div id="section-1">
  <strong>Section 1</strong>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
  incididunt ut labore et dolore magna aliqua.</p>
</div>
<div id="section-2">
  <strong>Section 2</strong>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor 
  incididunt ut labore et dolore magna aliqua.</p>
</div>
<div id="section-3">
  <strong>Section 3</strong>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor 
  incididunt ut labore et dolore magna aliqua.</p>
</div>

The JavaScript

Then, I added jQuery, the ScrollTo plugin, and my plugin to the page:

<script src="jquery.js"></script>
<script src="jquery.scrollTo.js"></script>
<script src="jquery.nav.min.js"></script>

Finally, I just need to call my plugin on the navigation:

$(document).ready(function() {$('#nav').onePageNav();});

Options

There are a few options for this plugin:

  • currentClass: 'current'

    Class to add to the list item when the navigation item is selected
  • changeHash: false

    If you want the hash to change when the user clicks on the navigation, change this to true
  • scrollSpeed: 750

    Speed to scroll the page when the navigation is clicked

And that’s it. Check out the demo and download the plugin from GitHub.

53 Comments

dxtr

11.11.2010

great and thank you for sharing ! but it doesn’t seem to work with ie 6 - well .. i know but ...    :/ 
any idea ? ....

Trevor

11.12.2010

@dxtr-
I didn’t even test in IE6. Fixed positioning isn’t supported so you would have to make some modifications to the CSS to even get it to look correctly.

Pixi

12.05.2010

Hello,

This script is great and what I was looking for however it creates a conflict with the other scripts of my site and I don’t know how can I add noconflict? Can you help me please? Thanks in advance.

Trevor

12.05.2010

@Pixi-
What do you mean you are having a conflict? Is there a specific error?

Emil

12.09.2010

Trevor,
There is a small bug with internet explorer (all versions, including 9),

For some reason IE does not bind the ‘scroll.onePageNav’, and therefore the currentClass does not get applied when scrolling the page.

I know that there is an IE issue with binding event to absolutely positioned elements, but i did not look into it.

Trevor

12.11.2010

@Emil-
Thanks for letting me know.

VJ

12.22.2010

Hello,

When I put an external link to the menu, other than links with anchors, the script stops working and makes some other scripts stop working as well. What may be the reason of this?

Trevor

12.22.2010

@VJ-
Can you provide a link?

VJ

12.22.2010

@Trevor-
Thanks for getting back to us. We just emailed you the link. Thank you in advance.

Underlog

12.27.2010

Hi, i’m new with jquery, and i wonder what is de .do class in the jquery code, at the end of the source code of your demo, thanx!

Trevor

12.27.2010

@Underlog-
You can ignore that if you just want to use the plugin. But if you want to know just so that you understand, it is appending a paragraph to the 4th section when the link it clicked. It’s purpose was to demonstrate that the plugin would still work even if content was dynamically added.

Underlog

12.27.2010

Amazing! thank you so much!

Mark

01.05.2011

Hey,
I have a bug and dont know how do I fix it.
Im using your JS scripts and the JS scripts from “colorbox”.
An he is using “http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js”

When I use
“http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js”
it doesnt scroll to the section it jumps to it and “colorbox” is working.

And when I delete
[removed][removed]

it scrolls to the section (your part is working) but colorbox works not.

Can you or somebody else help me?

thx

Mark

01.05.2011

i meant when I delete http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js
out of my html code.

it scrolls to the section (your part is working) but colorbox works not.

Trevor

01.09.2011

@Mark-
Make sure you are using the latest version of Colorbox.

IvanB

01.10.2011

This worked like a charm! Used it in my university project. Thank you very much!

Mark

01.10.2011

Trevor, Im using the last version of colorbox.
I’ve seen you’re using too the colorbox, is’nt it?
I dont know where the problem is. I’ve also already dowloaded the latest 1.4. jquery to my pc. Maybe there are the same varaibles in your script and in colorbox which were using?

Trevor

01.10.2011

@Mark-
Do you have a link to your page? Are you getting a specific error?

Borg

01.11.2011

Hi, I got a little question.
Here they only use one menu, I want to use the script on a website with 3 menu’s, this is what I did:

$(document).ready(function() {
  $(’#nav2’).onePageNav();
$(’#nav3’).onePageNav();
$(’#nav’).onePageNav();

Now this works but sometimes if i go from lets say #nav2 to #nav1 one of the 3 links (I got 3 links each #nav) will be dead, not doing anything. Is there a better way to use multiple menu’s?

Thanks

Trevor

01.11.2011

@Borg-
Do you have a link to your page? I’m confused as to why you could have 3 separate menus.

Borg

01.12.2011

@Trevor

Thanks for quick reply,

this is the link http://www.hetstilleseizoen.be/purt/index.html

Trevor

01.12.2011

@Borg-
The requirements for your page don’t seem to really suit this plugin very well. I would write a short custom script instead to solve your problem.

Borg

01.12.2011

Again thanks for the quick reply.

Can u tell me what I did wrong and for the short code, can u give me some information? I m not that good with Jquery or Javascript. Don’t realy know how to get started at the script.

VJ

01.12.2011

Hello,

A couple of weeks ago we wrote a comment about putting an external link into the menu, it breaks the script and other scripts on the page as well. We want to find the reason of it. Maybe you can help us. You asked for our website link and we sent it by writing in your contact page. We haven’t heard from you since. Maybe you haven’t received the message. How can we give our link to you other then writing it as a comment?

Trevor

01.12.2011

@VJ-
I emailed you back on 12/26 to the email address that you submitted in the contact form. Did you not receive it?

Trevor

01.13.2011

@Borg-
Sorry, I can’t just write all of the code for you. The reason that your site doesn’t really suit the plugin is because the plugin is intended to use a single menu on the page.

VJ

01.13.2011

Sorry we just checked our spam folder as well but couldn’t find your email. Maybe we missed it somehow. Can you email us again if it is possible to this address? Thank you for your response. We appreciate it.

Alex

01.17.2011

This is awesome! Thanks so much!

Kris

01.28.2011

My menu isn’t at the top and I wanted to change the scrollTo to match my menu offset, so I added offset to the code. And it worked wonderful!

here:
  onePageNav.bindNav = function($el, $this, curClass, changeHash, scrollSpeed, navOffset)

here:
  $.scrollTo(newLoc, scrollSpeed, { offset: -navOffset,

and here:
  $.fn.onePageNav.defaults = {
  currentClass: ‘current’,
  changeHash: false,
  scrollSpeed: 750,
  navOffset: 0
  };

Now I can give the offset during the menu initiate!

Is there a way so the menu is no longer fixed after the last menu-item is reached?

Trevor

01.28.2011

@Kris-
Nice addition with the navOffset. I’m not sure what you mean by making it not fixed anymore. Can you explain in more detail?

Kris

01.30.2011

@Trevor

Nevermind the fixed question, after some thinking I believe my problem is one I have to deal with outside your plugin. But thnx for your answer!

I have an other problem and don’t know how to fix.

I want to change the highlight/ current class of the “#menu li”, when the “#menu”-top is equal to “#section”-top.

Now it looks like the highlight/ current class changes when the “#section” passes 50% of the windows height.

Can I change this?

Trevor

01.31.2011

@Kris-
You will want to modify this line:
windowHeight = Math.round($(window).height() / 2);

Kris

02.01.2011

@Trevor
Thnx, that did the trick!

I have it now like this: 

  onePageNav.getSection = function(windowPos, navOffset) {
    // edit this section for change “current”-class on scroll
    var returnValue = ‘’,
      windowHeight =  navOffset || Math.round($(window).height() / 2);
   
    for(var section in onePageNav.sections) {
      if((onePageNav.sections[section] - windowHeight) < windowPos) {
      returnValue = section;
      }
    }
    return returnValue;
  };

And if I don’t set the navOffset, it will revert to it’s normal behaviour.

Ivaylo

02.04.2011

Thanks for the script.

I ’m experiencing two problems. Firstly, the navigation links do not highlight as I scroll through the page. Also, when inspecting , I get an error ‘TypeError: Result of expression ‘divPos’ [null] is not an object.’ on line 56.

Trevor

02.04.2011

@Ivaylo-
Do you have a link to your page?

Ivaylo

02.04.2011

Sure, I posted it using the contact form.

Ivaylo

02.05.2011

Everything worked fine for me, following your advice to do the rest of IDs referenced in the anchor links. However, Opera does not highlight the navigation sections while scrolling. I tested your demo page, just in case I’d screwed something up…

Trevor

02.05.2011

@Ivaylo-
I didn’t even look at this in Opera so I can’t really vouch for what it looks like.

Olly Killick

02.15.2011

Thanks, I will be using this soon. You are a gentleman and a scholar.

Borg

02.20.2011

Hi
I want to make the content scroll but I don’t want to see a scrollbar.
So i restricted the height of the content box to 100% of the screen
and I used this  

          overflow:hidden;

to hide the scrollbar and other content but now the script won’t work anymore.
Any suggestions?

Thanks,

Borg

Borg

02.20.2011

I found this trick on the internet to make it work
put this in your css.

html {
overflow:hidden;
}

sorry for the dum question :P

Chris

02.20.2011

@kris
@Trevor

I was looking for clarity on the navOffset value.  I also have an offset menu, however when I put in the navOffset value of 250 in the jquery.nav.js file nothing changed.

Trevor

02.20.2011

@Chris-
Did you modify the jquery.nav.js file like Kris mentioned?

Chris

02.21.2011

@Trevor

Yes I modified line 26:
onePageNav.bindNav = function($el, $this, curClass, changeHash, scrollSpeed, navOffset) {


Line 34 : $.scrollTo(newLoc, scrollSpeed, { offset: -navOffset,

and Lines 116-121 : 
  $.fn.onePageNav.defaults = {
  currentClass: ‘current’,
  changeHash: false,
  scrollSpeed: 750,
  navOffset: 300,
  };

Trevor

02.21.2011

@Chris-
I think you need to do more than just that. Kris changed the onePageNav.getSection function.

Chris

02.21.2011

@Trevor
I thought that function modification was for adjusting the highlight current class execution. However, I inserted that function change too and it didn’t help with the offset problem.

Trevor

02.21.2011

@Chris-
Sorry man, I’m not sure what else Kris had to do to make those changes.

Chris

02.21.2011

@Trevor
Hey no problem.  Thank you for responding so promptly and thank you for the plugin.

Shaun of the Web

02.28.2011

Great thing. I’ve used it for my website with x and y scrolling.

Chad Kaufman

03.02.2011

Is it possible to scroll the nav so the current item is lined up with the top of the intended section?

I have a nav with large buttons and some sections with only a little content. When the section lines up with the top of the page, there are times when the nav button no longer lines up the the section that was clicked.

Notice in the example below when clicking on Nav item #4 it scrolls passed the section:

http://ckurl.org/example/

Any help to resolve this would be greatly appreciated.

Trevor

03.02.2011

@Chad Kaufman-
You will want to change this line:

$.scrollTo(newLoc, scrollSpeed, {

To account for the offset of your navigation.

max

03.07.2011

thanks for sharing this script!

Chris

03.14.2011

THIS IS AMAZING!!!

What do you have to say?