|
||||||||
|
|||||||
|
|
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:
<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>
<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>
Browser compatibility
The javascript snippet above was tested on the following user agents:
*: 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.
Script Rating | |||||||||||||||||||||||||||||||||||||||||||||
| |||||||