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.
Categories
Recent Articles
February 2012
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 |
84 Comments
dxtr
11.11.2010great 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.2010Hello,
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.2010Trevor,
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.2010Hello,
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.2010Hi, 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.2010Amazing! thank you so much!
Mark
01.05.2011Hey,
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.2011i 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.2011This worked like a charm! Used it in my university project. Thank you very much!
Mark
01.10.2011Trevor, 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.2011Hi, 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.2011Again 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.2011Hello,
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.2011Sorry 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.2011This is awesome! Thanks so much!
Kris
01.28.2011My 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.2011Thanks 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.2011Sure, I posted it using the contact form.
Ivaylo
02.05.2011Everything 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.2011Thanks, I will be using this soon. You are a gentleman and a scholar.
Borg
02.20.2011Hi
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.2011I 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.2011Great thing. I’ve used it for my website with x and y scrolling.
Chad Kaufman
03.02.2011Is 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:
To account for the offset of your navigation.
max
03.07.2011thanks for sharing this script!
Chris
03.14.2011THIS IS AMAZING!!!
sanch3z
03.30.2011Hi Trevor,
Great script thanks for making it available. I’ve got it working but would like to use images (up, rollover and in-state) for my navigation, I know this isn’t great for SEO but the font and colours are really important. Can you point me in the direction of how to get images working with this great script?
Sanch.
Trevor
03.30.2011@sanch3z-
You can just use the CSS background-image property to style your navigation.
sanch3z
03.30.2011@Trevor-
Thanks for such a speedy response. So are you suggesting a different background-image for each item in the li list?
Thanks Sanch.
Olly Killick
03.30.2011@Sanch
I’ve used that technique here:
http://www.ollykillick.com/test
sanch3z
03.30.2011@olly & @Trevor,
Great site and great community cheers guys ;)
Joe
04.01.2011Hi Trevor,
does this have to be used for anchor links? I’m looking at line 52: onePageNav.getPositions = function($this) {
I have a set of buttons which already scroll down the page using ScrollTo, I’m trying to see if this script can be modified to change the class of the buttons.
Trevor
04.01.2011@Joe-
You could certainly change it to work with buttons.
Joe
04.01.2011@Trevor
Thanks for a quick reply. I made my life easier by putting <a> tags inside the buttons. It works a treat.
I’m now trying to get it to work with an offset. I change the 3 lines of code as per Kris’ post in the comments, but nothing seems to change regardless of values I put in. The quest continues…
Good job though!
Joe
04.05.2011Got this working now as I’d hope, good work.
Sadly IE is still causing a problem, I think it’s the same one mentioned by Emil further up the comments.
When the page loads (view my link on my name) IE recognises the window location and correctly applies the class. But, it does not change the class as the window scrolls.
Is there a workaround for this?
Olly Killick
04.07.2011Hi Trevor,
I am having an issue with linking directly to a particular section of the page.
For instance if you want to link a page to a portfolio section you would use http://myportfolio.com#portfoliosection
So when it lands on the page you don’t have to scroll to the section you want.
This works fine but I noticed when you do it, it highlights the first section of the nav even though you are in a different section of the page. For instance if you copy/paste the following URL into a browser window it highlights ‘section-1’ even though you have landed in ‘section-4’:
http://trevordavis.net/play/jquery-one-page-nav/#section-4
Is there a way to detect what section you are in, not on loading the page but on entering the page without having to click the nav?
Thanks,
Olly.
Trevor
04.07.2011@Olly Killick-
The link to my demo page you posted highlights section 4 for me.
Olly Killick
04.07.2011Thanks Trevor. I am experiencing the problem on Opera/IE8/Firefox 4—Win XP and OSX respectively, will try on Win 7 later. It works correctly on Chrome and Safari.
Hope this helps, I’m trying to find a way around it.
Olly Killick
04.07.2011Hey Trevor,
A firend of mine just sent me this, I’ve yet to implement but he says it works:
Hey try adding this line after the initiation of the script
$(’#nav’).onePageNav();
$(document).triggerHandler(‘scroll.onePageNav’);
Joana
04.10.2011Hello Trevor, thank you very much for this plugin, i’ve been searching for something like this for hours!
I’m quite a newbie on this kind of stuff so sorry if i’m asking a dumb question, but i really don’t know how to solve this.
The buttons of my menu are images and i want them to change to another images. I followed your steps, i checked and compared my code with your code and even with Olly Killick’s test page, but i don’t really know where is my mistake. I’ll leave you my link so you can see what is happening: http://oupasdesign.com/cla/segunda.html . Has you can see, when in top, the correspondent button to that section is “pushed” (orange) but when i start scrolling it changes to white (the original image) and i can never see it again pushed, even if i scroll back to the same position.
Can you understand my point? :x and if so can you help me, please?
Thank you very much, and sorry for any kind of inconvenience that i may have caused.
Take care :)
Trevor
04.10.2011@Joana-
You just need to use a descendant selector to change the images:
Joana
04.11.2011Thank you Trevor! It worked in part. Now it’s giving me some kind of error, but i think that is my fault and have nothing to do with this. I’ll try to fix it somehow. Thanks! :D
Olly
04.13.2011I wonder if, when scrolling manually you could make it snap to the section start points. Just an idea.
Trevor
04.13.2011@Olly-
Feel free to fork the code and make that change because I don’t think that is something that I will add into the plugin.
Olly
04.13.2011Yeah I think I’ll try my hand at a little JQuery. Thanks Trevor—I’ll post the source code somewhere if I manage to make it work.
Marlane
04.17.2011Hi there,
I’m using your plug-in on a new project and it works pretty fine!
I was wondering if it’s planned to have an “easing” option soon (maybe working with the easing plug-in?)...
I have tried to hack your code adding an easing method line 34:
$.scrollTo(newLoc, scrollSpeed, {easing:‘elasout’}
Works.
But now, if I click my nav, the highlight on the menu on scroll doesn’t work anymore.
I don’t understand what’s going on. Do you have a clue?
Thx =)
Trevor
04.17.2011@Marlane-
Are you getting any JS errors after clicking the link? Do you have a link to the page?
Nate
04.20.2011I’m trying to figure out how to get this plugin to work with a logo that links back to the top of the page, much like the way they do it on the Crush+Lovely site. The logo is in an <h1> right above the <ul> with the nav items.
Trevor
04.20.2011@Nate-
So do you have a section in the nav that also links back to the top of the page?
Nate
04.20.2011@Trevor
No, the nav doesn’t have an item that goes to the top. The logo goes to the top of the page, where a header section is located. The first item in the nav goes to a section just below the header.
Trevor
04.20.2011@Nate-
Ah ok. So the easiest thing to scroll to the top would be to just use the scrollTo plugin (which is required for this plugin) to just scroll the window to the top. And then you could remove the class of current on the nav if you need to.
Nate
04.21.2011@Trevor
Thanks for taking the time to reply. I’m pretty new to jQuery (and JavaScript), so I may just be doing something wrong. This is what I have:
$(’#logo a’).click(function(){
$.scrollTo(0, 750);
$(’#nav .current’).removeClass(‘current’);
return false;
});
I think it doesn’t work because the onePageNav function is still watching the page for scrolling, and it re-adds the current class to the nearest section as the page scrolls.
Trevor
04.21.2011@Nate-
Something like this might do it for you:
Nate
04.25.2011@Trevor
That fixed it! Thanks for all the help, and thanks for the great plugin.
Andrew
04.28.2011@Trevor. Great plugin! Thanks for writing it. I have a small question about it. I have it implemented on a site I am working on and it works great, except in one regard. When you reduce the size of the window horizontally, next time you click on a navigation element it moves the main body area under the navigation. Any thoughts on how to stop this from happening? The test site is: http://andrewpautler.com/clients/page2music/
Trevor
04.28.2011@Andrew-
Looks like it has to do with the scrollTo plugin. In the settings, it defaults to scrolling both the x & y axes. You should be able to specify just y and you should be good to go.
Andrew
04.28.2011@Trevor. I tried setting the axis to only one dimension, but that doesn’t seem to fix it. Oh well, I’ll keep trying. Thanks for your help.
Too late, comments are closed!
Don’t worry, you can email me or contact me on Twitter.