Having a menu at the top of the screen with inner anchor
Posted on: June 24, 2013
If you want to have a menu that will change what is selected depending of where you are on the screen, this can be done. First, you need to define your menu. Second, you need to have anchor inside your webpage. This is done by setting id to some element of your page. The example below has set id to 3 links. We could have set the id to H1 tag also.
1<ul id="top-menu">2 <li class="active"> <a href="#">Home</a> </li>3 <li> <a href="#header1">Header 1</a> </li>4 <li> <a href="#header2">Header 2</a> </li>5 <li> <a href="#header3">Header 3</a> </li>6</ul>78<a id="header1">This is my header 1</a>9<p>Text here ...</p>10<a id="header2">This is my header 2</a>11<p>Text here ...</p>12<a id="header3">This is my header 3</a>13<p>Text here ...</p>
The next step is to write some Javascript code that will use the scroll position to know what is the active anchor. The Javascript will also verify if a link is clicked.
1var lastId,2topMenu = $("#top-menu"),3topMenuHeight = topMenu.outerHeight()+15, // All list items4menuItems = topMenu.find("a"), // Anchors corresponding to menu items5scrollItems = menuItems.map(function(){ var item = $($(this).attr("href"));6if (item.length) { return item; } });78// Bind click handler to menu items9// so we can get a fancy scroll animation10menuItems.click(function(e){11 var href = $(this).attr("href"),12 offsetTop = href === "#" ? 0 : $(href).offset().top-topMenuHeight+1;1314 $('html, body').stop().animate({ scrollTop: offsetTop }, 300);15 e.preventDefault();16});1718// Bind to scroll19$(window).scroll(function(){20 // Get container scroll position21 var fromTop = $(this).scrollTop()+topMenuHeight; // Get id of current scroll item22 var cur = scrollItems.map(function(){23 if ($(this).offset().top < fromTop)24 return this;25 });26 // Get the id of the current element27 cur = cur[cur.length-1];28 var id = cur && cur.length ? cur[0].id : "";29 if (lastId !== id) {30 lastId = id;31 // Set/remove active class32 menuItems.parent()33 .removeClass("active")34 .end()35 .filter("[href=#"+id+"]")36 .parent()37 .addClass("active");38 }39});
Finally, the last step is to set the CSS to have a fixed menu that will stay at the top of the screen.
1body {2 height: 6000px;3}45#top-menu {6 position: fixed;7 z-index: 1;8 background: white;9 left: 0;10 right: 0;11 top: 0;12}1314#top-menu li {15 float: left;16}1718#top-menu a {19 display: block;20 padding: 5px 25px 7px 25px;21 -webkit-transition: 1s all ease;22 -moz-transition: 1s all ease;23 transition: 1s all ease;24 border-top: 3px solid white;25 color: #666;26 text-decoration: none;27}2829#top-menu a:hover {30 color: #000;31}3233#top-menu li.active a {34 border-top: 3px solid #333;35 color: #333;36 font-weight: bold;37}3839#header1{40 position: absolute; top: 400px;41}4243#header2{44 position: absolute; top: 800px;45}4647#header3{48 position: absolute; top: 1200px;49}
Here is an example, the code is pretty the same as here. I have adapted the code here for this blog. The credit goes to the person who has posted it on JsFiddle.
If you want to have an existing website that use that technic, you can go see http://letsmake.github.com/bettertogether/ which use this type of menu and effect.