This is a floating javascript menu.
Some links:
JTricks.com Home; Multilinks
Javascript Tricks, Code Samples and Snippets
/ JTricks.com Home / Navigation / Absolute Floating Menu
Last updated: 10 Dec 2007
Absolute Floating 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.

The javascript shown here allows to create dynamic menus which move along with scrolling. Such menu will be always visible. The effect is achieved my moving an absolutely-positioned DIV containing the menu code.

The floating menu will visibly move towards the specified viewing area spot, slowing as it moves closer to it and finishing the move with a visible snap. Such animation will definitely draw user attention to the floating menu.

Fixed & Sticky Menu will pin the menu to the spot if the browser supports it, moving it if not.
Script demonstration
Look for the floating box somewhere on the page.

Click the buttons to move the floating 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. For example:
<div id="floatdiv" style="
    position:absolute;
    width:200px;height:50px;left:0px;top:0px;
    padding:16px;background:#FFFFFF;
    border:2px solid #2266AA">
This is a floating javascript menu.
</div>
  • Insert the following code after this DIV:
<script type="text/javascript"><!--
/* Script by: www.jtricks.com
 * Version: 20071210
 * Latest version:
 * www.jtricks.com/javascript/navigation/floating.html
 */
var floatingMenuId = 'floatdiv';
var floatingMenu =
{
    targetX: -250,
    targetY: 10,

    hasInner: typeof(window.innerWidth) == 'number',
    hasElement: document.documentElement
        && document.documentElement.clientWidth,

    menu:
        document.getElementById
        ? document.getElementById(floatingMenuId)
        : document.all
          ? document.all[floatingMenuId]
          : document.layers[floatingMenuId]
};

floatingMenu.move = function ()
{
    if (document.layers)
    {
        floatingMenu.menu.left = floatingMenu.nextX;
        floatingMenu.menu.top = floatingMenu.nextY;
    }
    else
    {
        floatingMenu.menu.style.left = floatingMenu.nextX + 'px';
        floatingMenu.menu.style.top = floatingMenu.nextY + 'px';
    }
}

floatingMenu.computeShifts = function ()
{
    var de = document.documentElement;

    floatingMenu.shiftX =
        floatingMenu.hasInner
        ? pageXOffset
        : floatingMenu.hasElement
          ? de.scrollLeft
          : document.body.scrollLeft;
    if (floatingMenu.targetX < 0)
    {
        if (floatingMenu.hasElement && floatingMenu.hasInner)
        {
            // Handle Opera 8 problems
            floatingMenu.shiftX +=
                de.clientWidth > window.innerWidth
                ? window.innerWidth
                : de.clientWidth
        }
        else
        {
            floatingMenu.shiftX +=
                floatingMenu.hasElement
                ? de.clientWidth
                : floatingMenu.hasInner
                  ? window.innerWidth
                  : document.body.clientWidth;
        }
    }

    floatingMenu.shiftY = 
        floatingMenu.hasInner
        ? pageYOffset
        : floatingMenu.hasElement
          ? de.scrollTop
          : document.body.scrollTop;
    if (floatingMenu.targetY < 0)
    {
        if (floatingMenu.hasElement && floatingMenu.hasInner)
        {
            // Handle Opera 8 problems
            floatingMenu.shiftY +=
                de.clientHeight > window.innerHeight
                ? window.innerHeight
                : de.clientHeight
        }
        else
        {
            floatingMenu.shiftY +=
                floatingMenu.hasElement
                ? document.documentElement.clientHeight
                : floatingMenu.hasInner
                  ? window.innerHeight
                  : document.body.clientHeight;
        }
    }
}

floatingMenu.doFloat = function()
{
    var stepX, stepY;

    floatingMenu.computeShifts();

    stepX = (floatingMenu.shiftX + 
        floatingMenu.targetX - floatingMenu.nextX) * .07;
    if (Math.abs(stepX) < .5)
    {
        stepX = floatingMenu.shiftX +
            floatingMenu.targetX - floatingMenu.nextX;
    }

    stepY = (floatingMenu.shiftY + 
        floatingMenu.targetY - floatingMenu.nextY) * .07;
    if (Math.abs(stepY) < .5)
    {
        stepY = floatingMenu.shiftY + 
            floatingMenu.targetY - floatingMenu.nextY;
    }

    if (Math.abs(stepX) > 0 ||
        Math.abs(stepY) > 0)
    {
        floatingMenu.nextX += stepX;
        floatingMenu.nextY += stepY;
        floatingMenu.move();
    }

    setTimeout('floatingMenu.doFloat()', 20);
};

// addEvent designed by Aaron Moore
floatingMenu.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 = element[listener + '_num'] -1; i >= 0; 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']++;
};

floatingMenu.init = function()
{
    floatingMenu.initSecondary();
    floatingMenu.doFloat();
};

// Some browsers init scrollbars only after
// full document load.
floatingMenu.initSecondary = function()
{
    floatingMenu.computeShifts();
    floatingMenu.nextX = floatingMenu.shiftX +
        floatingMenu.targetX;
    floatingMenu.nextY = floatingMenu.shiftY +
        floatingMenu.targetY;
    floatingMenu.move();
}

if (document.layers)
    floatingMenu.addEvent(window, 'onload', floatingMenu.init);
else
{
    floatingMenu.init();
    floatingMenu.addEvent(window, 'onload',
        floatingMenu.initSecondary);
}

//--></script>
  • The target_x and target_y variables represent the desired distance from the top left corner of the menu to the window borders. Positive values mean distance from left and top border and negative - from right and bottom.
  • 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 Ok.
Microsoft Internet Explorer 7.0 Ok.
Internet Explorer 6.0 Ok.
Opera Opera 8.x Ok.
Opera 9.x Ok.
KHTML Konqueror 3.5.5 Ok.
No Javascript or
Javascript turned off
Any Menu will be absolutely positioned on initial style left and top values and will not move.

Script Rating
If you like our script, please rate it @ hotscripts.com!
 
© JTricks.com 2005-2007. All rights reserved.