Balloon Tooltips That Follow the Cursor
Tooltips don't need to be fancy. But putting tooltips in balloons is a nice change from the plain old rectangular ones. In the code below, the balloon will be to the left of the word(s) with the tooltip on it if the word is on the right side of the screen and it will be to the right of the word if the word is on the left of the screen.
The Balloon Tooltips That Follow the Cursor test page will work on Windows IE 5.5, 6, 7, 8, Safari, Chrome, Firefox, Opera, and . . . that's all we tested. If you want the graphics, they are balloon-left.gif and balloon-right.gif. If you want the tooltip to be still instead of following the cursor, you'll want Balloon Tooltips, and if you want rectangular boxes that need no graphics, you'll want Rectangular Tooltips.
The coding was fairly straightforward for all browsers except Firefox. Because of the weird way it does events, there wasn't that many ways to write cross-browser code that would satisfy it. We succeeded, but not until testing a lot of ways that did NOT quite work right. The other browsers were easy to program for, and plenty of ways of coding the tooltips-in-balloons script worked fine for them. We wish Firefox would start supporting normal event handling like the other browsers do.
The code discussion follows.
The CSS styling has transparency so the balloon, which is beneath it, shows through. It has hidden text overflow so that anything more than a balloon full will be invisible. In the test page, we overloaded the balloon just to test that and, as you can see, the overflow did indeed vanish. One need not center the text. Align it left if you like. One need not use border-bottom:1px solid blue on the words that pop up a tooltip, but you will want to do something—at least text coloring—so they know there's a tooltip waiting for them if they hover the trigger words with the mouse cursor.
Next we define the el() function to stick the tooltip text into an invisible box offscreen, with the use of innerHTML.
Then comes the wherecursor() function, which figures out exactly where the cursor is so it can use these coordinates to figure out where to put the tooltip text and balloon graphic. The flag keeps the graphic from being unwilling to disappear when there's a mouseout event in the HTML in the page body, when used with the if statement further down in this function. The CSS display property is either none (invisible and not in the flow) or block (visible and in the page flow) in our code. The 4 lines with all the e characters are standard cross-browser mouse cursor reading. Next comes the image decider—if the cursor is over 500px toward the right, the image whose id is abc will be used. It's the balloon with the pointer on the right that comes up on the left of the tooltip triggering word. If it's not over 500, the image with the id xyz will appear. It's the balloon with the pointer on the left that comes up on the right of the tooltip triggering word. The variable pp will get a different value depending on the over-500 criterion, and this will be used to adjust the horizontal position of the balloon correctly. The texttip box with the id texttip will also get positioned at this time, with its horizontal position similarly adjusted using pp. The s variable will be determined in the next function and since it's global it can be used in this function. The tooltip() function is used before the wherecursor() function, so this will work. Since s is the number of characters in the tooltip text, it stands to reason that the vertical position of the tooltip text will be adjusted for neatness with s.
In the tooltip() function the first action is to determine s, the number of characters in the tooltip text. If the texttip div is not around, the el() function will display it with the tooltip text stuck in it via innerHTML. As with the last function, next comes the image decider—if the cursor is over 500px toward the right, the image whose id is abc will be used. It's the balloon with the pointer on the right that comes up on the left of the tooltip triggering word. If it's not over 500, the image with the id xyz will appear. It's the balloon with the pointer on the left that comes up on the right of the tooltip triggering word. Then the image div and the tooltip text div will get their CSS display property changed from none to block, but placed offscreen, since we don't have enough data to determine their onscreen placement at this juncture. Then we register an event handler to an element, that is: to make sure a certain script runs when a certain event takes place on a certain HTML element. The element is document, the event is onmousemove, and the script is wherecursor. The reason there is no () after the script—a function—is because then the function would be executed and its result would be registered to onmousemove. This is not what we want, we merely want the function to be executed when the event takes place. Note that function wherecursor(e) has an e as parameter even though no parameter was sent. The e is for event. IE (and most other browsers) doesn't want or need the e—it makes its own using window.event. But Firefox requires it and cannot deal with window.event. This weakness is just plain dumb, IMHO. Firefox uses the parameter e for cursor position determination, whereas IE and others use window.event.
Then we have the bye() function in which both balloon images and the texttip div get dumped into a black hole of nonexistance via the display property getting changed to none, so they can no longer be seen since they're no longer around. This is run when the user leaves the word that trips the tooltip. It's run by the mouseout event.
Now we declare 4 divs. The 2 image divs and the texttip div get the CSS style display:none. Black hole nonexistance again. The fourth div is the pile of words with the special span tags in it. These tags have the onmouseover and onmouseout events to popup and disappear the tooltips.
<html>
<head>
<style type="text/css">
#texttip {
padding: 4px;
background-color: transparent;
text-align: center;
font-size: 13px;
overflow:hidden;
z-index:999}
span.tip {border-bottom:1px solid blue;color:blue}
</style>
<SCRIPT LANGUAGE="JavaScript">
<!--
var x=0;
var y=0;
var xx = 12;
var yy = 10;
var pp = 0;
var b;
var s=0;
var w=0;
var u="";
var tt;
var flag=0;
function el(thetooltip){
tt = document.getElementById('texttip');
tt.style.display = 'block';
tt.innerHTML = thetooltip;}
function wherecursor(e){
flag=flag+1;
if (!e) var e = window.event;
if (e.pageX){x = e.pageX;y = e.pageY;}
else if (e.clientX){x = e.clientX + document.body.scrollLeft;y = e.clientY + document.body.scrollTop;}
var t = document.getElementById('texttip');
if (x>500){pp=0;b = document.getElementById('abc');}else{pp=310;b = document.getElementById('xyz');}
b.style.left = (pp+x+xx-310) + 'px';
b.style.top = (y+yy-120) + 'px';
if(flag==1){b.style.display = 'block';}
t.style.left = (pp+x+xx-300) + 'px';
if(s<200){w=25;}else{w=0;}
t.style.top = (w+y+yy-122) + 'px';}
function tooltip(thetooltip){
u=thetooltip.toString();
s=u.length;
if(!document.getElementById('texttip')) el(thetooltip);
var t = document.getElementById('texttip');
t.innerHTML = thetooltip;
if (x>500){b = document.getElementById('abc');}else{b = document.getElementById('xyz');}
b.style.display = 'block';
b.style.left = '-1999px';
t.style.display = 'block';
t.style.left = '-1999px';
document.onmousemove=wherecursor;}
function bye(){document.getElementById('texttip').style.display = 'none'; document.getElementById('abc').style.display = 'none'; document.getElementById('xyz').style.display = 'none';}
// -->
</script>
</head>
<BODY SCROLL="auto" BGCOLOR="#FFFFFF">
<center><h1>Balloon Tooltips That Follow the Cursor</h1></center>
<div id='abc' style='z-index:998;position:absolute;display:none;top:300px;width:300px;height:100px;'><IMG SRC="balloon-left.gif" WIDTH=300 HEIGHT=100 BORDER=0 id='i1'></div>
<div id='xyz' style='z-index:998;position:absolute;display:none;top:300px;width:300px;height:100px;'><IMG SRC="balloon-right.gif" WIDTH=300 HEIGHT=100 BORDER=0 id='i2'></div>
<div id='texttip' style='z-index:999;position:absolute;display:none;top:300px;width:270px;height:80px;'> </div>
<div style='background-color:#fff;z-index:99;position:absolute;left:50px;top:100px;width:900px;'>
<p><b>Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah.</b> Here is a bunch of dumb text and you can hover the word <span class="tip" onmouseover="tooltip('You will see my 2nd great and wonderful tooltip right here. You will see my 2nd great and wonderful tooltip right here. You will see my 2nd great and wonderful tooltip right here. You will see my 2nd great and wonderful tooltip right here. You will see my 2nd great and wonderful tooltip right here. You will see my 2nd great and wonderful tooltip right here. You will see my 2nd great and wonderful tooltip right here. You will see my 2nd great and wonderful tooltip right here. You will see my 2nd great and wonderful tooltip right here. You will see my 2nd great and wonderful tooltip right here. You will see my 2nd great and wonderful tooltip right here');" onmouseout="bye();">tooltip</span> to see the tooltip come up. <b>Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah.</b> Here is a bunch of dumb text and you can hover the word <span class="tip" onmouseover="tooltip('You will see my 1st great and wonderful tooltip right here');" onmouseout="bye();">tooltip</span> to see the tooltip come up. <b>Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah.</b></p>
</div>
</body>
</html>