position absolute does not go above a dropdown (<select>...)

J

Joachim Bauer

I'm using the code below to display a menu that opens when the mouse
goes over the main menu item (try it in your browser to understand the
behaviour).

It uses "position:absolute" and a switch between "display='none'" and
"display=''".

However the problem is that
- in Internet Explorer 6 the dropdown (<select>...) always hides the
menu
- in Mozilla the menu is hidden initially but after clicking on the
text "Select" it isn't hidden.

How does that come and how can I overcome it?
I want the menu to be above the other stuff when it comes up.

Regards,
Joachim


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<head>
<title>Menu Example</title>
</head>
<body>
<form method="get" action="target.jsp" name="myForm">
<TABLE id="acGeneralMainMenuItem" border="1" rules="none"
cellspacing="0" bordercolor="blue">
<TR class="tableMenuRow">
<TD NOWRAP ONMOUSEOVER="showSubmenu('acGeneralSubmenu',this,'acGeneralMainMenuItem');"
ONMOUSEOUT="hideSubmenu('acGeneralSubmenu');">
&nbsp;General menu&nbsp;<br>
<TABLE id="acGeneralSubmenu"
border="1" rules="none" cellspacing="0" bordercolor="blue"
style="display:none; position:absolute;">
<TR class="tableMenuRow">
<TD NOWRAP id="generalMenuItem0" onclick=
"document.getElementsByTagName('form')[0].actionSelected.value='f158';document.getElementsByTagName('form')[0].submit()"

ONMOUSEOVER="highlightMenuItem('generalMenuItem0');"

ONMOUSEOUT="lowlightMenuItem('generalMenuItem0');">
&nbsp;General item 1&nbsp;
</TD>
</TR>
<TR class="tableMenuRow">
<TD NOWRAP id="generalMenuItem1"
onclick="document.getElementsByTagName('form')[0].actionSelected.value='f159';document.getElementsByTagName('form')[0].submit()"
ONMOUSEOVER="highlightMenuItem('generalMenuItem1');"
ONMOUSEOUT="lowlightMenuItem('generalMenuItem1');">
&nbsp;General item 2&nbsp;
</TD>
</TR>
<TR class="tableMenuRow">
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<p>
<input type="hidden" name="actionSelected" value="">
Select
<SELECT name="f145">
<OPTION value="*" selected>*</OPTION>
<OPTION value="option1">option1</OPTION>
<OPTION value="option2">option2</OPTION>
<OPTION value="option3">option3</OPTION>
<OPTION value="option4">option4</OPTION>
<OPTION value="option5">option5</OPTION>
<OPTION value="option6">option6</OPTION>
<OPTION value="option7">option7</OPTION>
<OPTION value="option8">option8</OPTION>
<OPTION value="option9">option9</OPTION>
</SELECT>
</form>




<script type="text/javascript">
<!--
// Define a global variable to hold the id of the submenu showed the
last time
var lastSubmenuShown='';

// Define a function to show the submenu at an absolute position
relative to
// the main menu item's position within the parent element.
// The structure of the main menu item and the submenu is:
// <TABLE id="acGeneralMainMenuItem" ...>
// <TR ...>
// <TD NOWRAP ONMOUSEOVER="showSubmenu('acGeneralSubmenu',this,'acGeneralMainMenuItem');"
// ONMOUSEOUT="hideSubMenu('acGeneralSubmenu')">
// General Actions<br>
// <TABLE id="acGeneralSubmenu" style="display:none;
position:absolute;"
// <TR ...>
// <TD NOWRAP id="..."
// ONCLICK="script to execute action associated with
submenu item"
// ...
// >Action1</TD>
// ...
//
// Parameters:
// submenuId: the id of the submenu to be shown
// parent: the parent of the main menu item
// mainMenuItemId: the id of the main menu item
function showSubmenu(submenuId,parent,mainMenuItemId)
{ // Hide last submenu
if (lastSubmenuShown!='') hideSubmenu(lastSubmenuShown);

// Initialize yOffset with the height of the main menu item minus 2
var yOffset=document.getElementById(mainMenuItemId).offsetHeight-2;
var x = 0;
var y = yOffset;
do {
x += parent.offsetLeft;
y += parent.offsetTop;
} while ( parent = parent.offsetParent );

var e = document.getElementById( submenuId );
e.style.left = x + 'px';
e.style.top = y + 'px';
e.style.display = '';
var xMax = document.body.scrollLeft + document.body.clientWidth;
if ( x + e.clientWidth > xMax ) {
e.style.left = ( xMax > e.clientWidth ?
( xMax - e.clientWidth ) : 0 ) + 'px';
}

if ( y + e.clientHeight > document.body.scrollTop +
document.body.clientHeight ) {
y -= e.clientHeight + ( yOffset ? yOffset : 0 );
e.style.top = ( y > e.clientHeight ? y : 0 ) + 'px';
}

lastSubmenuShown=submenuId;

return false;
}

// Define a function to hide the submenu
// Parameters:
// submenuId: the id of the submenu to be hidden
function hideSubmenu(submenuId)
{ document.getElementById(submenuId).style.display = 'none';
return false;
}

// Define a variable to hold the id of the last menu item highlighted
var lastHighlightedMenu='';

// Define a function to highlight a menu item
function highlightMenuItem(menuItemId)
{ if (lastHighlightedMenu!='') lowlightMenuItem(lastHighlightedMenu);
document.getElementById(menuItemId).setAttribute('bgcolor','#aaaaff','false');
lastHighlightedMenu=menuItemId;
}

// Define a function to lowlight a menu item
function lowlightMenuItem(menuItemId)
{ document.getElementById(menuItemId).setAttribute('bgcolor','white','false')
}
//-->
</script>


</body>
</HTML>
 
G

Grant Wagner

Joachim said:
I'm using the code below to display a menu that opens when the mouse
goes over the main menu item (try it in your browser to understand the
behaviour).

It uses "position:absolute" and a switch between "display='none'" and
"display=''".

However the problem is that
- in Internet Explorer 6 the dropdown (<select>...) always hides the
menu

<select> is the only remaining windowed element, it is always positioned over other elements.

- in Mozilla the menu is hidden initially but after clicking on the
text "Select" it isn't hidden.

By default the background-color of the table is probably "transparent". Changing the style definition from:
style="display:none; position:absolute;
to
style="display:none; position:absolute;background-color:white;"

Seemed to resolve the problem. Also, you probably shouldn't be using setAttribute() and "bgcolor". You'd be far better off changing:

document.getElementById(menuItemId).setAttribute('bgcolor','white','false')
to:
document.getElementById(menuItemId).style.backgroundColor = 'white';

And when setAttribute() does take a 3rd parameter, it is supposed to be an integer, not a string. By passing the string 'false', it
evaluates to true so you're actually passing the opposite value to what you are intending. More on setAttribute() at <url:
http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/setattribute.asp />, but as I said, you'd be better off using
..style.backgroundColor = ...
How does that come and how can I overcome it?
I want the menu to be above the other stuff when it comes up.

Defining a background-color on the table style seems to resolve the problem in Gecko-based browsers, but in IE, there is no way of
keeping a <select> from appearing on top of every other element.
 
J

Joachim Bauer

Grant, thanks for your hints. I wrote a workaround for I.E.'s stupid
behaviour to keep <select> above everything else. It is hiding all
<select>s that overlap with my menus. It is done with the function
below which is called in showSubmenu and in hideSubMenu in case of
navigator.appName is "Microsoft Internet Explorer".

// Define a function to show/hide the select controls
// that overlap with the menu
// Parameters:
// actions: may be 'hide' of 'show'
// x: the x position of the menu
// y: the y position of the menu
// width: the width of the menu
// height: the height of the menu
function showHideSelectControls(action,x,y,width,height)
{ var right=x+width-1;
var bottom=y+height-1;

var selectControls=document.getElementsByTagName("select");
for (var i=0; i<selectControls.length; i++)
{ if (action=='hide')
{ var sx=selectControls.offsetLeft;
var sy=selectControls.offsetTop;

// sx and sy are relative to parent. Compute absolute values
var parent=selectControls.offsetParent;
do {
sx += parent.offsetLeft;
sy += parent.offsetTop;
} while ( parent = parent.offsetParent );

var sRight=sx+selectControls.offsetWidth-1;
var sBottom=sy+selectControls.offsetHeight-1;

if (bottom >= sy
&& (x >= sx && x <= sRight
||
right >= sx && right <= sRight))
selectControls.style.visibility='hidden';
}
else selectControls.style.visibility='visible';
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,526
Members
44,997
Latest member
mileyka

Latest Threads

Top