DOM Scripting: Internet Explorer Version 6 MouseOver :hover
Internet Explorer 6 is notorious for a virtually endless list of software bugs, imperfections and deviations from W3C Web Standards that make it an unbearable thorn in the side of every Web Standards-conscious web developer. To make things worse (at least in 2006), it is the most widely used web browser followed by the more standards compliant Mozilla Firefox, Internet Explorer 7, Safari, Opera among others. Much as many a front-end Web Developer would prefer to ignore the capricious irregularities (from the box model to the peek-a-boo bug) of this browser, and forge ahead with standard XHTML, CSS and DOM scripting, business requirements always oblige us to write hacks for IE6 often late at night in an attempt to make deadlines while including IE6.
At hand is a bug that has used up a good amount of my time as I have tried many approaches to properly trigger events in IE6. The objective is to build a menu using XHTML strict, CSS and DOM scripting to semantically layout content, style it with CSS and control expandable menus using Javascript. The basic idea is to trigger modify the CSS display value of an unordered list or DIV (that contains sub-menu items) when the user hovers the parent menu item, and when he mouse leaves the parent item and the sub-menu items. I am running into a tough situation that makes IE6 Windows in particular to close the menu when the mouse is not exactly on top of text within a DIV or a UL LI item that makes a menu item.
Troubleshooting results indicate that this is happening because; unlike the other browsers (Opera, IE7, Firefox), IE6 does not consider the empty space around an element inside a container to be an active part of the container. As documented on many sites, IE6 does not recognise a mouseover or :hover event on anything that is not on an <A> active item. In addition, it does not consider the border of a box/container to be inside that container. As such, when for example I mouse-over the parent menu item in my example and expand the menu, moving from one child item to another crosses over some inactive space and the open menu closes.
Probable paths to explore for a solution
I thought that this was only happening with menus based on a UL LI (List item) hierarchy, and so I rebuilt the menu using a hierachy of DIV elements belonging to various classes... I ran into the same exact obstacle as detailed above.
Solution paths
One walk-around it to code a delay into the function that closes the menu so that it waits for a moment to see if the mouse is on-top of an active item, if not, closes the menu. This delay approach setTimeout("myfunction('')",time); seems to work, but after the delay it closes the menu anyway regardless of the mouse position.
Setting a status flag that has to be verified before a closeMenu() function can be run. In theory, this approach will not suffer from the drawbacks of delaying the closing of the child menu.
I am currently doing additional research on solving this issue without compromising the code quality. If you can think on an approach, or event a simple idea that could provide a remedy to the IE6 characteristic, please let me know and I will be infinitely thankful.



Comments
Empty DIV space not firing onMouseOver in IE solution
PS: This question was sent to me via email
------------------------------
I came across your article, "DOM Scripting: Internet Explorer Version 6
MouseOver :hover", while looking for a solution to exactly the problem you
describe. I didn't find one. I set out to come up with a solution myself on
the basis of knowing that:
a) the problem is empty space, and
b) there are plenty of things we can put into empty space that won't actually be
visible. The most obvious to me was a borderless table set to 100% width,
and that worked. Just wrap a table around each menu item's text, and the
onMouseOver attribute of the DIV will fire off when you mouse over the
"empty" space.
MenuItem
It may not look pretty when you can see the code, but the effect is worth
it if you ask me. Please let me know what you think of this solution.
Thanks.
Solution: Increase the size of the active area
The challenge outlined above can be resolved by creating a walk-around the the Internet Explorer issue of not recognising onMouseOver events triggeredby non-active elements. So if we somehow make the active area span the entire space, then we can give the impression of being able to trigger the event from the empty space around the link, while actually making the link as big as the available space.
Increase the active area of the link by placing CSS to pad the inside of the link object so that it is big enough to fill the available space. This can easily be accomplished by not styling the containing element, but rather the HREF element itself Make the active mouse-over area a link, and make sure it covers the entire area required by using CSS to expand the size of the "a href"
i.e with this XHTML code<div id="someID">
<a href="#" onmouseover='alert("event triggered")' onmouseout='alert("event closed")'>
<span class="otherclass">This is the linked text here that will take up as much space as possible, and be hidden/cut-off if it overflows the allowed area</span>
</a>
</div>
body #someID a
{
padding: 3px;
}
as opposed to padding the non-active part of the content
Since IE6 will only implement hover on active elements, you can fill the area with text or an image, set overflow:hidden; so that it does not mess up your layout, and then make the text/image invisible (not the link, but the contained ), and there you have a seemingly active empty space.
with this/same XHTML code
<div id="someID">
<a href="#" onmouseover='alert("event triggered")' onmouseout='alert("event closed")'>
<span class="otherclass">This is the linked text here that will take up as much space as possible, and be hidden/cut-off if it overflows the allowed area</span>
</a>
</div>
CSS
#someID
{
/*make this invisible if it gets bigger than the set size*/
overflow: hidden;
width: 100px;
height: 100px;
}
#someID a .otherclass
{
visibility: hidden; /*hide the content, but let it take up space and be active*/;
}
Have you seen http://www.grc.com/menu2/invitro.htm
I've tried it out with both ie6 and ie7, and neither seem to have the bug you've mentioned.
Best of luck.
My solution.
- Set the LIs that contain your anchors to have overflow:hidden.
- Set a line-height and padding for your anchors.
This should expand your anchor's hover area to the whole area of the containing LI, don't ask me why though.
In my case the css looks something like this:
li ul li { width:150px; font-size:10px; margin-bottom:-2px; overflow:hidden; }
li ul li a { padding:5px; line-height:15px; }
Hope this helped.
Added with with javascript
Hi, I found this issue and it was the same I was facing when building my DOM css semantic correct ajax javascript menu.
What I did to solve this issue: (a note: i did this with mootools (.org), a leightweight flexible javascript toolbox) I wrote a javascript function which asks for the width of the menuItems, then set the width property (css) with javascript. this works like a charm and is quite neat!
function addWidth(parent)
{
$ES('a',parent).each(function(element){
var maxWidth = element.getSize().size.x;
element.setStyle('width',maxWidth + 'px');
});
this can also be done w/o mootools. $ES is a function which retrieves elements of type 'a' within element parent (which in my case is a div holding menuitems). Goodluck!
You can get an "empty" DIV
<div id="txtContainerButtons" style="position:absolute;
top:96px; left:731px; height:60px; width:40px;
background-color:green;" onmouseover="alert('over!');"
onmouseout="alert('out!');">
<img src="transparent.gif" style="height:100%;
width:100%;">
</div>
same problem-stupid solution
--css--
I don't have idea why, but it works for me.li {
height:1%;/this makes li active, not only text in <a>
}
.
.
--structure of menu--
menu is part of bigger table
<td>
<div...>
<ul>
<li onmouseover... onmouseout...>Menu /show and hide this li and div id=me
<div id=me >
<ul><li><a>submenu1</a></li></ul>
<ul><li><a>submenu10..</a></li></ul>
</div>
</li>
</ul>
</div>
</td>
I 'dislike' microsoft.