So, we just launched www.treasury.gov on SharePoint 2010 in the Amazon cloud. During the course of this project we came across some interesting issues with SharePoint 2010 and I want to report our findings. The first issue we had to deal with is what we called the menu sticking issue.
Before describing the issue, let me explain our menu system. The asp.net menus, in SharePoint 2010, have a property called simple rendering. If this property is true, the menu system is list based (i.e.: ul/li). If this property is false, the menu system is table based. Best practices say that this should be true (i.e.: list based). However, our menu was designed with a fixed width and each section of the menu had a different width to match the word in it. So, it is a very rigid menu in terms of styling. Unfortunately, the simple rendering (i.e.: list based) menus in SharePoint do not put a unique id on each list item. So, we couldn’t size the items for our particular design with that type of menu. Thus, we had to go with the table based menu because each section gets assigned a unique id that we can size through css. I’m not sure if there is any correlation between using table vs list based menus and the bug we found, but I thought it is important to point out.
The second thing to note about our menus is that we use the hover property of the SharePoint asp.net menu to turn the background white when the user hovers over it. Thus, the menu looks like this when a user hovers over a particular section of the menu:
Image may be NSFW.
Clik here to view.
Sticking Issue
The “sticking” issue was a bug that was reported that baffled us at first. We were getting reports that the menu was getting stuck in a hover state. In fact, the background was getting stuck on white and the foreground was getting stuck on white too. It looked like the section of the menu didn’t even exist. Here is an example of what the issue looked like:
Image may be NSFW.
Clik here to view.
The biggest problem with the issue is that we had problems reproducing it. It seemed to happen intermiddently. Eventually we found out how to reproduce it. Basically, it only happend if the user moved their mouse over the menu during the page load. For some reason, when the page loaded up, if the users mouse was moving over the menu, this would happen.
Weird, right? So, I had do dig into what SharePoint was doing to create the hover state and it all has to do with javascript. Basically, the menu system builds this javascript in the page (near the bottom):
spBodyOnLoadFunctionNames.push(‘enableFlyoutsAfterDelay’);
Menu_HoverStatic = overrideMenu_HoverStatic;
Those two javascript methods can be found in the dynamic axd script that the SharePoint menu creates and they look like this:
function overrideMenu_HoverStatic(item)
{ULSxSy:;
if (!flyoutsAllowed)
{
setTimeout(delayMenu_HoverStatic(item), 50);
}
else
{
var node=Menu_HoverRoot(item);
var data=Menu_GetData(item);
if (!data) return;
__disappearAfter=data.disappearAfter;
Menu_Expand(node, data.horizontalOffset, data.verticalOffset);
}
}
function enableFlyoutsAfterDelay()
{ULSxSy:;
setTimeout(“flyoutsAllowed=true;”, 25); }
So, to simplify what they are doing, they are basically putting the mouse hover into an endless loop that only works when the attribute “flyoutsAllowed” gets set to true. That attribute gets set to true on a 25 millisecond delay after the page onLoad event happens.
It seems like they are trying to enforce the entire page gets loaded before the hover event takes place. Now, here in lies the issue. They don’t use a similar technique on the unhover. So, technically, the unhover can happen before the hover because of this technique used.
I went through this code a bunch of times and for the life of me I couldn’t figure out “why” they were doing it. It was pretty obvious “what” they are doing. But, I never found a reason “why”. You don’t need to wait for the page to load for hovers to work. One could assume they wanted to ensure all the html was there for the hover. But, this javascript gets ran at the end of the file, so it is a pretty good assumption it will be there. I came to the conclusion that there was no reason for this hover delay and that this is causing our menu “sticking” issue.
Luckily, SharePoint used a javascript override technique to build their function. So, all I had to do was copy their override method, take out the check for flyoutsAllowed, and the issue was fixed. I just put the following code into my custom .js file on my SharePoint site:
function overrideMenu_HoverStatic(item)
{
var node=Menu_HoverRoot(item);
var data=Menu_GetData(item);
if (!data) return;
__disappearAfter=data.disappearAfter;
Menu_Expand(node, data.horizontalOffset, data.verticalOffset);
}
That was it, the menu “sticking” issue was fixed. We tested this in all major browsers (even the dreaded IE6). We found no issues caused by this fix. I’m not sure why this bug hasn’t been reported yet. Maybe it has to do with out specific situation (SharePoint 2010, table based menus, with background changing on hover state). So, if anyone has a similar issue with this situation, mabye this blog will help you out.