/ JTricks.com
/ Navigation
/ Fixed & Sticky Menu
Last updated: 27 Nov 2007
Fixed & Sticky Menu
Many web pages don't fit on most users' screens. The visitors have to scroll to read the page contents.
Such scrolling however hides the navigation menus usually located at the top of the page.
Newer browsers (such as Firefox or Internet Explorer 7) support
position:fixed
CSS option to pin something to particular window place. However page layout will
be ruined if it is not supported by the browser. The javascript sample here will try
to use position:fixed
if available, falling back to moving
DIV with position:absolute
if fixed positioning isn't available.
Most notable browser not to support position:fixed
is Internet
Explorer 6, which is still widely used when this article was written.
Absolute Floating Menu will provide floating menu with slow movement effect towards the desired spot.
Script demonstration
Look for the fixed menu box somewhere on the page.Click the buttons to move the fixed menu to different corners:
Script source code
To use the script perform the following steps:- Create a DIV
element with id of 'floatdiv' which contains the menu markup. Please note that
it should have
osition:absolute
(which will be changes on the fly toposition:fixed
by through javascript if it is supported by the browser). Initial position should be specified vialeft
,right
,top
,bottom
CSS properties. For example:
<div id="fixeddiv" style=" position:absolute; width:200px;height:50px;right:10px;top:10px; padding:16px;background:#FFFFFF; border:2px solid #2266AA"> This is a (Javascript/CSS) Fixed menu. </div>
- Insert the following code after this DIV (or put in separate file and reference it):
<script type="text/javascript"><!-- /* Script by: www.jtricks.com * Version: 20071127 * Latest version: * www.jtricks.com/javascript/navigation/fixed_menu.html */ fixedMenuId = 'fixeddiv'; var fixedMenu = { hasInner: typeof(window.innerWidth) == 'number', hasElement: document.documentElement != null && document.documentElement.clientWidth, menu: document.getElementById ? document.getElementById(fixedMenuId) : document.all ? document.all[fixedMenuId] : document.layers[fixedMenuId] }; fixedMenu.computeShifts = function() { fixedMenu.shiftX = fixedMenu.hasInner ? pageXOffset : fixedMenu.hasElement ? document.documentElement.scrollLeft : document.body.scrollLeft; if (fixedMenu.targetLeft > 0) fixedMenu.shiftX += fixedMenu.targetLeft; else { fixedMenu.shiftX += (fixedMenu.hasElement ? document.documentElement.clientWidth : fixedMenu.hasInner ? window.innerWidth - 20 : document.body.clientWidth) - fixedMenu.targetRight - fixedMenu.menu.offsetWidth; } fixedMenu.shiftY = fixedMenu.hasInner ? pageYOffset : fixedMenu.hasElement ? document.documentElement.scrollTop : document.body.scrollTop; if (fixedMenu.targetTop > 0) fixedMenu.shiftY += fixedMenu.targetTop; else { fixedMenu.shiftY += (fixedMenu.hasElement ? document.documentElement.clientHeight : fixedMenu.hasInner ? window.innerHeight - 20 : document.body.clientHeight) - fixedMenu.targetBottom - fixedMenu.menu.offsetHeight; } }; fixedMenu.moveMenu = function() { fixedMenu.computeShifts(); if (fixedMenu.currentX != fixedMenu.shiftX || fixedMenu.currentY != fixedMenu.shiftY) { fixedMenu.currentX = fixedMenu.shiftX; fixedMenu.currentY = fixedMenu.shiftY; if (document.layers) { fixedMenu.menu.left = fixedMenu.currentX; fixedMenu.menu.top = fixedMenu.currentY; } else { fixedMenu.menu.style.left = fixedMenu.currentX + 'px'; fixedMenu.menu.style.top = fixedMenu.currentY + 'px'; } } fixedMenu.menu.style.right = ''; fixedMenu.menu.style.bottom = ''; }; fixedMenu.floatMenu = function() { fixedMenu.moveMenu(); setTimeout('fixedMenu.floatMenu()', 20); }; // addEvent designed by Aaron Moore fixedMenu.addEvent = function(element, listener, handler) { if(typeof element[listener] != 'function' || typeof element[listener + '_num'] == 'undefined') { element[listener + '_num'] = 0; if (typeof element[listener] == 'function') { element[listener + 0] = element[listener]; element[listener + '_num']++; } element[listener] = function(e) { var r = true; e = (e) ? e : window.event; for(var i = 0; i < element[listener + '_num']; i++) if(element[listener + i](e) === false) r = false; return r; } } //if handler is not already stored, assign it for(var i = 0; i < element[listener + '_num']; i++) if(element[listener + i] == handler) return; element[listener + element[listener + '_num']] = handler; element[listener + '_num']++; }; fixedMenu.supportsFixed = function() { var testDiv = document.createElement("div"); testDiv.id = "testingPositionFixed"; testDiv.style.position = "fixed"; testDiv.style.top = "0px"; testDiv.style.right = "0px"; document.body.appendChild(testDiv); var offset = 1; if (typeof testDiv.offsetTop == "number" && testDiv.offsetTop != null && testDiv.offsetTop != "undefined") { offset = parseInt(testDiv.offsetTop); } if (offset == 0) { return true; } return false; }; fixedMenu.init = function() { if (fixedMenu.supportsFixed()) fixedMenu.menu.style.position = "fixed"; else { var ob = document.layers ? fixedMenu.menu : fixedMenu.menu.style; fixedMenu.targetLeft = parseInt(ob.left); fixedMenu.targetTop = parseInt(ob.top); fixedMenu.targetRight = parseInt(ob.right); fixedMenu.targetBottom = parseInt(ob.bottom); if (document.layers) { menu.left = 0; menu.top = 0; } fixedMenu.addEvent(window, 'onscroll', fixedMenu.moveMenu); fixedMenu.floatMenu(); } }; fixedMenu.addEvent(window, 'onload', fixedMenu.init); //--></script>
- Be sure to verify page design with the Javascript turned off.
Browser compatibility
The javascript snippet above was tested on the following user agents:Mozilla/Netscape | Firefox 2.0.x | Ok *. |
Firefox 1.5 | Ok *. | |
Firefox 1.0.x | Ok *. | |
Netscape Navigator 4.79 | Downgrades gracefully ***. | |
Microsoft | Internet Explorer 7.0 | Ok *. |
Internet Explorer 6.0 | Jumpy **. | |
Internet Explorer 5.0 | Jumpy **. | |
Opera | Opera 9.x | Ok *. |
Opera 8.x | Ok *. | |
KHTML | Konqueror 3.5.5 | Ok *. |
No Javascript or Javascript turned off |
Any | Downgrades gracefully *. |
*: Ok means the browser supports
position:fixed
and the best
visual effect is achieved.**: Jumpy means the browser doesn't support
position:fixed
and a DIV
with position:absolute
is repositioned
when the page is scrolled.***: Graceful degradation means the box is shown in its initial place with
position:absolute
and
is not moved.
Donations and Script Rating
If you like our script, please |