I have a CSS based simple drop down menu with multi-levels. The second or third level might go outside the visible window, with certain combinations of resolution and window size.
Some pre-built menu controls just open the drop-down to the left instead of the right, if they detect this situation.
How can I test (with JS/jQuery) for this situation?
You can test if a menu item is offscreen with the following function:
/*--- function bIsNodeClippedOrOffscreen returns true if a node
is offscreen (without scrolling).
Requires jQuery.
*/
function bIsNodeClippedOrOffscreen (zJnode)
{
var aDivPos = zJnode.offset ();
var iLeftPos = aDivPos.left;
var iTopPos = aDivPos.top;
var iDivWidth = zJnode.outerWidth (true);
var iDivHeight = zJnode.outerHeight (true);
var bOffScreen = CheckIfPointIsOffScreen (iLeftPos, iTopPos);
var bClipped = CheckIfPointIsOffScreen (iLeftPos + iDivWidth, iTopPos + iDivHeight);
return (bOffScreen || bClipped);
}
function CheckIfPointIsOffScreen (iLeftPos, iTopPos)
{
var iBrowserWidth = $(window).width() - 16; //-- 16 is fudge for scrollbars, refine later
var iBrowserHeight = $(window).height() - 16; //-- 16 is fudge for scrollbars, refine later
var bOffScreen = false;
if (iLeftPos < 0 || iLeftPos >= iBrowserWidth)
bOffScreen = true;
if (iTopPos < 0 || iTopPos >= iBrowserHeight)
bOffScreen = true;
return bOffScreen;
}
.
Sample usage:
<li id="SomeMenuItem"> Get your shopping cart for free!
...
...
var Node = $("#SomeMenuItem");
var NeedToMoveIt = bIsNodeClippedOrOffscreen (Node);
You must display the element to get the size so display the sub-menu off screen. Get the width/height of the element, calculated expected display positions (right/bottom), compare to screen width/height, decide which location to display and move element to final position.
(untested example)
function displaysOffPageRight(defaultLeft){
$('#submenu1').addClass('displayOffScreen');
var offPage = defaultLeft + $('#submenu1').width() > screen.width;
$('#submenu1').removeClass('displayOffScreen');
return offPage;
}
When the menu is not yet displayed, you can't get its dimensions. to set its position. If you set CSS visibility: hidden
and display: none
, the menu will not be shown but it will have its dimensions defined. Then you can get it's position using jQuery.offset
and its height/width with jQuery.outerWidth/outerHeight
(pay attention to the margin
options for the latter functions). Oh, and be careful if you are using any negative margins, this would require special handling.
Get the window's dimensions with jQuery(window).height()
and .width()
and you should be able to figure out the math from there.