I set up a demo page here.
Download: Uncompressed | Minified | Zipped Demo | Github
I have tested this plugin in IE8, Firefox and Chrome. Please leave me feedback if you any problems with how it works or if it doesn't work in other browsers.
Setup
- This plugin requires jQuery in order to function properly.
- Follow the basic templates below to set this up on your site. For more details, go to the specific section.
- HTML
<div id="sidemenu"> <ul> <li><a href="#home">Home</a></li> <li><a href="#work">Work</a></li> <li><a href="#blog">Blog</a></li> <li><a href="#projects">Projects</a></li> <li><a href="#about">About</a></li> <li><a href="#contact">Contact</a></li> </ul> </div>
- Change the side menu id to whatever you want, just make sure you target it with the script.
- This side menu example will work with the plugin's default settings. See the alternate example of a different layout.
- CSS
#sidemenu { position: fixed; top: 50px; left: 20px; background: #444; width: 120px; } #sidemenu ul { list-style-type: none; margin: 0; padding: 0; } #sidemenu li { margin: 5px; padding: 5px; width: 100px; text-align: center; } #sidemenu li.selected { background: #555; } #sidemenu a { text-decoration: none; color: #bbbbff; } #sidemenu a:hover { color: #fff; }
- This CSS highly variable. Change the position, size and colors as desired.
- This CSS highly variable. Change the position, size and colors as desired.
- Script
$(document).ready(function(){ $('#sidemenu').visualNav(); });
- HTML
<div id="menu"> <div class="link" title="#Home">Home</div> <div class="link" title="#work">Work</div> <div class="link" title="#blog">Blog</div> <div class="link" title="#projects">Projects</div> <div class="link" title=".about">About</div> <div class="link" title=".contact">Contact</div> </div>
- This side menu uses divs with a title attribute. The value in this attribute can be used to target an Id or a class (which should be unique).
- It is important to note, that this menu will not work with javascript disabled, whereas the default one will work.
- CSS
#menu { position: fixed; top: 50px; left: 20px; background: #444; width: 120px; } #menu div.link { margin: 5px; padding: 5px; width: 100px; text-align: center; } #menu div.selected { background: #555; }
- Script
$(document).ready(function(){ $('#menu').visualNav({ link : 'div.link', targetAttr : 'title', selectedAppliedTo : 'div.link' }); });
This plugin has the following default options, so you will only need to include the line below in the script options if you want to change the default:
$('#sidemenu').visualNav({ link : 'a', // Add a link class, as necessary targetAttr : 'href', // added in case you have link = "div" and attribute something like selectedClass : 'selected', // css class applied to menu selectedAppliedTo : 'li', // to only apply to the link, use "a" topRange : 100, // measure from the top of the viewport to X pixels down topMargin : 100, // margin above the top where the target updates the menu bottomMargin : 20, // margin from the end of the page where the last menu item is used animationTime : 1200 // time in milliseconds });
- The first four options should were hopefully made clear in the examples above.
- To modify how the menu acts, you will need to adjust the "topRange", "topMargin" and "bottomMargin" values. I made this picture to better understand what these values do for you.
- topRange: The "topRange" is basically the area where target needs to be inside of in order for the menu to update. For example, the target (found in the link attribute) starts under the topRange. As it moves up and crosses into the topRange. The script then updates the side menu to show that the target area is in view (or inside the view port).
- topMargin: The top edge margin (topMargin) is the area above the view port. The top edge margin is used while the page is being scrolled up - the target is above the view port and as you scroll up, the target moves down. When the target is inside the edge margin, the menu will update and point to that target.
- bottomMargin: The bottom edge margin is the area below the view port. It is when the page is scrolled down (the contents are moving up). When the bottom of the page is inside the bottom edge margin, the menu will update with the last targeted id. This was necessary to be include in case the last section is too short and unable to reach the top range area.
- animationTime: The animation time is the time in milliseconds that the menu will scroll to the selected section.
- The menu will not select (or highlight) the item above the last item if they are both very short. For example, if your browser shows three sections while at the bottom of the page. The third to last may have shown for a brief time just before the bottom of the page reached the bottom edge margin. The menu would then skip directly to the last menu item. This is one reason why the bottom margin value is kept a low number (20 pixels by default).
- If you click on a menu item, the page contents will automatically scroll to that section and update the browser url with that target. But if you manually scroll the page using the scroll bar or mouse, the web page url will not update with the current position. This was done on purpose, because if the script changes the location, the page will jump to that target automatically. This wouldn't look good if you are quickly scrolling through the page as it would make the movement jittery.
- To make suggestions or report any bugs please email me at wowmotty at g mail dot com.
Updated to version 2.0... using a new algorithm to determine if the blocks are in the view port.
ReplyDeleteHi, great navigation tool. Just wondering how you would make it work for a horizontal scrolling page?
ReplyDeleteThanks in advance!
Hi loui83!
ReplyDeleteI have a version in the works that will have both horizontal and vertical scrolling... but I won't be able to release it for another week or so.
Hi, very nice plugin!
ReplyDeleteI am also curious about when the horizontal version is coming.
How about one that can move both vertical and horizontal?
I have seen some similar thing here; http://www.appelsiini.net/projects/viewport/3x2.html
But i read somewhere that this will not work in some browsers.
thanks anyway for a nice plugin.
O
Hi Info! Get the latest version on Github which works with vertical, horizontal or both page layouts. :)
ReplyDeleteThanks Mottie, i have downloaded it and will give it a try.
ReplyDeleteLooks good :)
Hi,
ReplyDeletehow do I add an external link to the menu?
@jo: Use one of the available methods to control the navigation.
ReplyDeleteHi again,
ReplyDeletesorry but the link didn't make much sense to me! If I am using the horizontal menu.. e.g I have five internal links and one in this menu linking to an external blog. How can I get it to open in a new window?
Opps! Sorry I misread your question. Basically you can just add a class to each menu link, then use the "link" option to target that class name. Here is a demo.
ReplyDeleteAha! Thanks so much! =)
ReplyDeleteHi, tried to use this with a horizontal menu (188px height) that is fixed on the top of the screen , what I need to do is to scroll the section linked in the menu and positioned it just below the menu instead behind and In can´t do it. please help me.
ReplyDeleteThanks in advance
Hi @Charlie Hdez!
ReplyDeleteTry this demo, maybe it will help guide you. Basically I added top padding to the ".content" to keep it below the menu.
Hey man, great plugin, only one problem i had, it doesn't really have a callback functionality. So i added my own, here is the updated code. please feel free to use or distribute my changes.
ReplyDeletehttp://pastebin.com/j74HR60m
Thanks! I'll include this in the next update, whenever I have some time to work on it!... you can follow the progress by checking on the issue (enhancement really) I opened at my github repository for this plugin.
DeleteHi Mottie,
ReplyDeleteI'm having a really good time implementing the visual navigation plugin. Thanks for sharing it.
Question. Can the scrolling animation speed be changed depending on the distance being the elements scrolled? Currently the 'animationTime' option works great, but some of my content is pretty long and having several different animation speeds would really spruce things up.
My aim is to have at least 5-6 different animation speeds based on as many different distances, all included in the options of the plugin so they can be tweaked for each implementation. Something like... 'scrollTime1: - scrollTime6:', and 'scrollDistance1: - scrollDistance6:'.
Thanks for the great work.
Hiya!
DeleteSorry for not responding earlier, but to modify the timing it would require some core code modification. I'll look into adding something that calculates the distance it needs to move, then change the time accordingly. Maybe set it to time/pixels (completely guessing here, but something like 100ms/100pixels)? I opened a repository issue to remind myself to add this... now if I just had some free time =/
I'm using the "Alternate" method - using DIVS. When I manually scroll the page, the links highlight properly. But when I click them, I get an error in Firebug's console:
ReplyDeleteTypeError: $sel.offset() is null
Something I did wrong? I'm 95% sure I did everything correctly. Triple checked the demo.. etc.
Hiya! Are you sure you have the "contentClass" name set correctly in the options? If you do, then I would need to see your HTML and plugin settings in order to better help you.
DeleteAnd since I downloaded the min, I didn't see those settings.
DeleteAwesome... works now. Thanks.
This plugin is excellent. It's just what I needed for a site I'm working on. Thanks for your hard work. You really should provide a "donate $$ for a license" link of some kind.
ReplyDeleteI'm having one small problem I hope you can help with. I've called your script on a pretty basic HTML layout with a fixed nav of UL/LI. The 'selected' LI is updating beautifully. And when I click one of the nav links, the page does go to the appropriate DIV. But it does not animate. It's a basic jump, working the way any traditional anchor would. I would really like the more aesthetically pleasing animation rather than this abrupt jump, but I can't get it to animate.
I have also imported jquery easing 1.3. Also, many of my content DIVs are styled with height:100% so they fit in the whole window. Could this be part of the problem?
Any thoughts?
It sounds like there might be a script error or some kind of interference. Press F12 in your browser, then check the console tab. See if there are any javascript errors that might interrupt the execution of javascript.
DeleteIf you can't find anything, it would make it easier for me to help if you shared a demo - modify this demo to try and replicate the issue. Thanks!
Thanks for the reply.
DeleteI switched to the non-mini script to get an actual line number:
Uncaught TypeError: Cannot read property 'left' of undefined, Line 76
I'm doing vertical scroll only, if that tells you anything.
I don't think I can really replicate my structure on jsFiddle, but I'll email you a link.
Thanks for any help you can offer. To reiterate: it WORKS, very nicely actually, I'm just hoping for the added bonus of a nice animated scroll when you click a nav link.
Thanks for the reply.
ReplyDeleteI switched to the non-mini script to get an actual line number:
Uncaught TypeError: Cannot read property 'left' of undefined, Line 76
I'm doing vertical scroll only, if that tells you anything.
I don't think I can really replicate my structure on jsFiddle, but I'll email you a link.
Thanks for any help you can offer. To reiterate: it WORKS, very nicely actually, I'm just hoping for the added bonus of a nice animated scroll when you click a nav link.
Wow, I totally forgot about these comments here. Now I'm not sure what the issue could be.
Delete* Are you using jQuery v1.3+?
* Is the HTML set up with each content block properly and has a class name of "content"?
* Does the link href match an ID or class name somewhere on the page? I know older IE has issues with mixed upper and lower cases in ID/classes.
Hi... I am a beginner and I am trying to incorporate the visualnav script into Twitter's Bootstrap framework.
ReplyDeleteI just want a simple smooth vertical scrolling animation. When you click on something, the page scrolls beautifully to the desired option.
Could you give any advice on this matter? Thank you.
Hi! I'm sorry it took me so long to respond, but I'll have to add instructions for this on my to do list. =(
DeleteOk I've finally gotten around to updating the plugin. Check out the new Bootstrap demo.
DeleteHi, Thanks so much, this is fantastic!
ReplyDeleteI have a question horizontal version. How can I make it automatically load to a given section. eg. it first loads to "section 3" instead of "section 1"? So when you first view the page you can scroll left or right, instead of just right.
Thanks
Just include the hash to the section... try this link: horizontal.html#projects
DeleteGreat, thanks so much for the response
DeleteHi Rob - love your plugin and just used it as a learning exercise to get it to work in a one page WordPress theme I'm working on.
ReplyDeleteAs a complete JS/jQ novice, it's been several days of disappointment culminating in that amazing EUREKA! moment we all love so much.
I was originally looking to combine 2 or even 3 plugins to achieve what I've been able to do with just yours - awesome!
Thank you very much for your hard work.
Mike :)
I'm glad you've found it useful! :)
DeleteLOL - there's always a question isn't there...
ReplyDeleteI'm having difficulty using a link in the menu to the internal blog page (posts page). Adding a standard link to the menu breaks the menu highlighting.
Secondly, once I'm on a different page, even one which uses the same menu I can't get back because the new page takes control of all the URLs.
i.e. Going from mydomain.com/#home to mydomain.com/blog means that after that, clicking menu items gives me mydomain.com/blog#home, mydomain.com/blog#about, mydomain.com/blog#contact etc.
Did I miss something?
Thanks :)
External links should get a class name of "external" added to them so that the plugin ignores them - the class name can be changed by changing the "externalLinks" option.
DeleteAs for linking from different pages, you'll need to change the links in your blog to point to "mydomain.com#home" (or maybe just "../#home") instead of "#home", or maybe I'm not understanding... why would you use the same links on a different page?
Hi Rob, i absolutely love your plugin!
ReplyDeleteBut i have a problem here... i can't figure how and were should i update the topMargin value... i need my content area to be placed arround 150px bellow the top of the browser...
Thanks in advance!
Hi Andre!
DeleteThe topMargin option is only for measurement. The problem with using the hash tag is that the browser forces the anchor to be at the top of the page; it ignores any margin and padding as well. This plugin updates the hash when the animation completes, so if you try to offset the top, it jumps back to the top edge of the anchor.
So, the best, cross-browser solution is to just add an anchor (link) above your content, then add a margin or padding to push the content down. Check out what I had to do for the bootstrap demo - I added a 50px top padding above the content.
:P Many thanks!!!! That do the trick!
DeleteAgain, thanks for all your work!
Hi!
ReplyDeleteExcuse me for poor english.
It's normal that Horizontal Navigation don't work properly on smartphones?
Hi Valentino!
DeleteI'm sorry I haven't had a chance to test this plugin on a smart phone. Last time I checked, the menu doesn't stay fixed because the css class "position: fixed" doesn't work.
What problem are you having?
Hi!
ReplyDeleteThank you for this GREAT script! I'm planning to use it in a vertical design. (How) can I make the hash update while scrolling?
Hi Bas Sijpkes!
DeleteThe problem is that when the hash changes, the browser automatically jumps to that element, so the page will jump while scrolling. There is one way around it and that is to rename all of the IDs on the page, this might be possible if your stylesheet doesn't use ID's for styles... either way, I don't have much time right now to implement something like that.