Webpage Tooltips

Today was fairly productive. I spent most of it bringing the data entry form up-to-speed with the input specification. I still have a lot to do tomorrow, but a lot of foundation has been set. I've fixed that bug in my tooltip code, so now I can share...

The popup function takes the div to show, and the event object from the onmouseover and onmouseout events. The nice thing about what I'm doing here is that you can format the DIV to be whatever you want in the editor (such as include hyperlinks and bulleted lists); just set the DIV to start out as visibility:hidden.

The function looks at the element that fired the event, and calculates it's true x & y position (adding the width of the element, so that the popup shows to the right of the control). Then it moves the DIV and shows or hides it.

function popup(ToolTipDiv, Event)
//Show the DIV if it is hidden
if (ToolTipDiv.style.visibility=='hidden')
//Store the element in a variable for use
var e = Event.toElement;
//The X & Y location to move the DIV to
var x = e.offsetWidth;
var y = 0;
//Here we walk up the tree, storing the offsets for each element and their parent.
x += e.offsetLeft;
y += e.offsetTop;
e = e.offsetParent;
} while(e != null)
//Finally, we move and then show the DIV
ToolTipDiv.style.top = y;
ToolTipDiv.style.left = x;
//Otherwise, we hide the DIV

This function is called by adding the two events to an element, replacing DivToShow and DivToHide with the id of same DIV: 

onmouseenter="popup(DivToShow, event);" onmouseout="popup(DivToHide, event);"

Two things came to mind when I was done:

  1. The need for looping through every offsetParent seems unusual. I suspect that there is a very simple property that I should be using. Earlier attempts at using simpler properties failed due to the heavily nested nature of the page, and the need to allow page scrolling. But maybe I missed the obvious.
  2. I'm thinking that, rather than storing the DIV ID twice in the element's definition, maybe I should do the work in the function. I would look at event.toElement.id, and decide within the function which DIV to show or hide using a SWITCH statement (or possibly just naming the DIV "ToolTip" + elementID). I still might do this, as I think it may improve maintainability (the lookups would take place in one location, rather than scattered throughout the page). This would have prevent a few minor bugs where the mouseout event was mistyped.

If you use this in a row with onmouseenter, you get a very interesting behavior: the tooltip will be to the right of whatever control the mouse is hovering over (as if the popup function was called from that element). If the cell has no text, the tooltip will show up to the right of the cell (covering other columns to the right).

Anyways, I hope this was interesting. Feel free to leave comments about the code; it's been a long time since I played with javascript.

[Edit: I found a couple bugs if you want to have interaction with the DIV, rather than just displaying text. You can see the fixed post here.]