View Full Version : tooltip bound to mouse, working with prototypes

06-08-2007, 04:28 AM
So, i'm trying to design a tooltip that sticks to the mouse when you hover over a list item. I'm also trying to use AJAX to fetch the text from an xml file. So far i don't have any issues with the AJAX (it doesn't get that far)
Here is the javascript:

// tooltip object here
var disconnect = 0;
function tt() {
this.tooltip = document.createElement('div');
this.tooltip.style.position = 'absolute';
this.tooltip.style.visibility = 'hidden';
this.tooltip.style.className = 'ttShad';
this.content = document.createElement('div');
this.content.style.position = 'relative';
this.content.className = 'ttContent';

// prototype for the show method of the tooltip
function tt.prototype.show(x, y) {
this.tooltip.style.left = x + 'px';
this.tooltip.style.top = y + 'px';
this.tooltip.style.visibility = 'visible';
if (this.tooltip.parentNode != document.body) {

// prototype for the hide method of the tooltip
function tt.prototype.hide() {
this.tooltip.style.visibility = 'hidden';
//a function to create and show a tooltip on the mouse
function tt.prototype.run(number) {
//set tooltip position by getting the mouse position
if (!e) {var e = window.event;}
var curseX = 0;
var curseY = 0;
if (e.pageX || e.pageY) {
curseX = e.pageX;
curseY = e.pageY;
else if (e.clientX || e.clientY) {
curseX = e.clientX + Geometry.getHorizontalScroll();
curseY = e.clientY + Geometry.getVerticalScroll();
x += curseX + Tooltip.OffsetX;
y += curseY + Tooltip.OffsetY;
//show the tooltip on the mouse
if(!text) {
FetchText(tooltip.php, number, 'insertText()');
var self = this;
var timer = window.setTimeout(function() {self.show(x, y); }, Tooltip.DELAY);
if(target.addEventListener) target.addEventListener('mouseout', mouseout, false);
if(target.attachEvent) target.attachEvent('onmouseout', mouseout);
else target.onmouseout = mouseout;
function mouseout() {
if(target.removeEventListener) {
target.removeEventListener('mouseout', mouseout, false);
else if(target.detachEvent) {
target.detachEvent('onmouseout', mouseout);
else target.onmouseout = null;

//Find a way to create an ajax request to get text
function FetchText(address, tooltip, handler) {
if(rip) {
if(disconnect == 20) {
if(!handler) {
var handler = 'insertText()'
else {
else if(!x_object) {
alert('Ajax not supported! :O Get a new browser!');
else if(x_object) {
document.body.tooltip.content.inner HTML='<img src="/images/ajaxloader.gif" alt="Ajax Loading" longdesc="A loading bar for ajax progress" />';
var url = address;
var error_timeout = 10;
var response_handler;
if(x_object == null)
var timeout_watch = setTimeout(function() { alert('Error, the stuffs timed out...'); }(error_timeout * 1000));
x_object.onreadystatechange = function() {
if(x_object.readyState == 4)
if(http_request.status == 200)
eval(handler + "(x_object);");
alert("No callback function \"" + handler + "\" exists.");
var rip = 1
var query_string = number;
x_object.open('POST', url, true);
x_object.setRequestHeader('User-Agent', 'XMLHttpRequest');
x_object.setRequestHeader('Accept-Language', 'en');
x_object.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
x_object.setRequestHeader('If-Modified-Since', lastRequestTime.toString());
x_object.send(query_string, handler);

function insertText(x_object) {
rip = false;
if(x_object == null)
alert('Unable to connect.. bad luck.')
var response = x_object.responseXML.documentElement;
var hco = getElementByTagName('hcontent');
var xsc = getElementByTagName('content');
if(!response.hco || !response.xsc)
alert('Server Error, try again! ...though maybe a bit later...');
document.body.tooltip.style.display = 'hidden';
else {
var header ='<div class="ttHead">' + response.hcontent.firstChild.data + '</div>';
var xmcontent ='<div class="ttText">' + response.content.firstChild.data + '</div>';
document.body.tooltip.content.inner HTML= header + xmcontent;

tooltip.tooltip = new tooltip()

function getRequestObject() {
if(ActiveXObject('Microsoft.XMLHTTP')) {
var x_object = new ActiveXObject('Microsoft.XMLHTTP');
else if(ActiveXObject('Msxml2.XMLHTTP') {
var x_object = new ActiveXObject('Msxml2.XMLHTTP');
else if(XMLHttpRequest()) {
var x_object = new XMLHttpRequest();

function FunctionExtant(name) {
var function_exists = false;
eval("if(typeof window." + name + " == 'function') { function_exists = true; }");
That's the javascript.
Heres the HTML for my implementation(which i suspect might be part of the problem, but i'm not experienced enough to sniff out problems).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="keywords" content="Stephen; Tutorials; Markup; Awesome; kickass; damn awesome; awesome; markup; tutorials;" />
<title>S - Index</title>
<script src="js/tooltip.js" type="text/javascript" language="javascript"></script>
<link rel="stylesheet" href="poised_ninja.css" />
<link rel="shortcut icon" href="favicon.ico" />
<script src="SpryAssets/SpryAccordion.js" type="text/javascript"></script>
<link rel="stylesheet" href="SpryAssets/SpryAccordion.css" type="text/css" />
<link rel="stylesheet" href="js/tooltip.css" type="text/css" />

<script type="text/javascript" language="javascript">
new tt();
<div id="container"> <img src="images/banner_v2.jpg" width="1098" height="145" alt="banner" />
<div id="featured"> <img class="top" src="images/top_image_hold_media.jpg" alt="banner" /> <img class="top" src="images/top_image_hold_media.jpg" alt="banner" /> <img class="top" src="images/top_image_hold_tsg.jpg" alt="banner" /> <img class="top" src="images/top_image_hold_tsg.jpg" alt="banner" /></div>
<div class="left_column">
<li onmouseover="tt.run(1)"><a href="index.html">Home</a></li>
<li onmouseover="tt.run(2)"><a href="tutorials.php">Testing Grounds</a></li>
<li onmouseover="tt.run(3)"><a href="news.php">News</a></li>
<li onmouseover="tt.run(4)"><a href="media.php">Media</a></li>
<li onmouseover="tt.run(5)"><a href="about.php">About</a></li>
<h3>Quick Links</h3>
<li onmouseover="tt.run(6)"><a href="http://www.digg.com">Digg</a></li>
<li onmouseover="tt.run(7)"><a href="http://www.ytmnd.com">YTMND</a></li>
<li onmouseover="tt.run(8)"><a href="http://www.thepiratebay.org.">The Pirate's Bay</a></li>
<li onmouseover="tt.run(9)"><a href="http://www.cheesycarrion.com">Cheesy Carrion</a></li>
<li onmouseover="tt.run(10)"><a href="http://www.carl.cheesycarrion.com">Carl</a></li>
<li onmouseover="tt.run(11)"><a href="http://www.owenx.farklem.com">Owen's Tutorials</a></li>

Also, hate to ask for more help, but it is hard to find examples of how to make a php ajax script on line, so i cooked this up but i'm not sure if there are any problems, i'm not very experienced with php or the ajax architecture.

$number = $_POST['query_string'];
$handler = $_POST['handler'];
$xml = simplexml_load_file("tooltip.xml");
echo $handler;
echo $xml->tooltip[$number - 1]->hcontent->asXML();
echo $xml->tooltip[$number - 1]->content->asXML();

06-08-2007, 05:35 AM
What's the problem you're having?

By looking at it, I think something to consider is leaving the styling and positioning out of the JS.
You can easily position the tooltip and style it with CSS.

eg: CSS

.tooltip_parent {
display: inline;
/* etc. etc.. */

.tooltip {
top: 20px;
right: 0px;
/* etc... etc... */

Then with your JS, attach the tooltip to the HTML Element it will be shown over (as a childNode) instead of the document body.

This is a faster on slower PCs and is a bit better separation of presentation and logic... probably simpler too..

I wrote a blog about the CSS tooltips a while back: http://fijiwebdesign.com/content/view/82/77/

It explains a bit better...

06-08-2007, 05:45 AM
Cool, thank you. I'll give that a shot.