var toolTip = null; //global reference to tool tip box var hideTimerHnd //reference to timer for hide/kill var displayTimerHnd //reference to timer for display var autoCloseTimerHnd //reference to autoclose timer /* Startup (default) settings*/ var defaultBg = "#DDECFF"; //default background color var defaultText = "#000"; //default text color /* Default settings (normally static, but interactive for demo) */ var imagePosition = "left"; //Alignment of image var textAlign = "right"; //Text Alignment var displayTime = 100; //display delay var hideTime = 0; //time to auto hide var autoCloseTime = 0; //Auto close var tipOn = false; // check if over tooltip link var Xoffset = 0; //horizontal offset for tip var Yoffset = 0; //vertical offset for tip var useLinkHeight = false; //vertical offset = link height plus Yoffset var followMouse= false; //Flag have tip follow mouse var openAtMouse = false; //Flag to open at mouse coordinates var skipCloseTimer = true; //Flag for auto close to bypass close delay /* Tips for interactive demo instructions */ var temp = ["...","...","..."]; var positioningText = temp.join(""); temp = [ "...","...","..."]; var mousexyText = temp.join(""); temp = [ "...","...","..."]; var delayText = temp.join(""); temp = [ "...","...","..."]; var imagePosText = temp.join(""); var textPosText = "<dl><dfn>Text Position<\/dfn>"; temp = null; /*Tool Tip content an array of arrays * (image, description, optional-bgColor, optional-textcolor) */ var messages = new Array(); messages[0] = ['filecab.gif','Here is a ...',"#FFFFFF"]; messages[1] = new Array('mboard.gif','Here is a ...',"#ccf"); messages[2] = new Array('books.gif','Here is a ...','Yellow','red'); messages[3] = new Array('books.gif','Position correction...','black','yellow'); messages[4] = new Array('mboard.gif','Position Correction...','lightgreen','black'); /* Instruction for demo no image */ messages[5] = new Array('',positioningText,'#ccc','black'); messages[6] = new Array('',mousexyText,'#ccc','black'); messages[7] = new Array('',delayText,'#ccc','black'); messages[8] = new Array('',imagePosText,'#ccc','black'); messages[9] = new Array('',textPosText,'#ccc','black'); /* preload images */ if (document.images) { var theImgs = []; for (var i=0; i < messages.length; i++) { if (messages[i][0] != "") { theImgs[theImgs.length] = new Image(); theImgs[theImgs.length -1].src = messages[i][0]; } } theImgs = null; }
/* Onmouseover event handler, gets event object, this-object for KHTML, and message array index */ function doTooltip(evt, num) { if (!toolTip) return; //If no element to show tip, just let it go. evt = evt || window.event; //capture window.event for IE and KHTML /* Clear timers */ clearTimers(); /* Check demo option settings, normally not part of toolTip */ checkOptionSettings(num); /* Restore default colors */ toolTip.style.color = defaultText; toolTip.style.backgroundColor = defaultBg; /* Set display colorsi,put text, image in toolTip div */ if (typeof messages[num][2] != "undefined") toolTip.style.backgroundColor = messages[num][2]; if (typeof messages[num][3] != "undefined") toolTip.style.color = messages[num][3]; if (typeof toolTip.innerHTML != "undefined") { if (messages[num][0]) { var pattern = '<img src="%src%" class="%cls%" >%txt%'; pattern = pattern.replace(/%[a-z]{3}%/g, _makePattern); toolTip.innerHTML = pattern; } else { toolTip.innerHTML = messages[num][1]; } } /* internal (nest) function for pattern */ function _makePattern(a) { switch (a) { case '%src%': return messages[num][0]; case '%cls%': return imagePosition; case '%txt%': return messages[num][1]; } } if (followMouse) { //Attach event handler to track mouse position document.onmousemove=trackMouse; } else if (openAtMouse) { trackMouse(evt); //Get a single instance of mouse X,Y showTip(); //Open delay not option for open at mouse } else { var evtObj = evt.target || evt.srcElement; /* Get reference to element triggering request for tip. * Some browsers register event on the text node * so there is a loop to the first element. */ while (evtObj.nodeType != 1) { evtObj = evtObj.parentNode || evtObj.parentElement; } /* Set top-left */ var coordinates = getCoordinates(evtObj); toolTip.style.left = coordinates.Xoffset + 'px'; toolTip.style.top = coordinates.Yoffset + 'px'; }//endif /* Set timer to show toolTip or show immediately */ if (displayTime > 0) displayTimerHnd = setTimeout(showTip, displayTime); else showTip(); }//eof doTooltip
/* Make tip visible, start auto close timer */ function showTip() { toolTip.style.visibility='visible'; /* There are 2 options to handle auto close. * The first auto below goes directly to killTip * and by-passes the close delay setting. * The second used hideTip and triggers the close delay. */ if (autoCloseTime > 0) { if (skipCloseTimer) autoCloseTimerHnd = setTimeout(killTip, autoCloseTime); else autoCloseTimerHnd = setTimeout(hideTip, autoCloseTime); }//endif }//eof showTip
/* remove toolTip*/ function killTip() { if (toolTip) { toolTip.style.visibility = "hidden"; document.onmousemove=""; //Stop using resourcese /* This next code is for demo */ resetMouseOptionDisplay(); } }//eof killTip
/* Mouseout event handler. * Clear display timer in case tip not yet displayed * and kill tip or set timer to kill */ function hideTip() { if (toolTip) { if (displayTimerHnd) clearTimeout(displayTimerHnd); if (hideTime > 0 && toolTip.style.visibility == "visible") { hideTimerHnd = setTimeout(killTip, hideTime); } else { killTip(); } } }//eof hideTip
function clearTimers() { if (displayTimerHnd) clearTimeout(displayTimerHnd); if (hideTimerHnd) clearTimeout(hideTimerHnd); if (autoCloseTimerHnd) clearTimeout(autoCloseTimerHnd); }
/* onMouseMove event handler. * Positions toolTip to mouse X,Y */ function trackMouse(evt) { if (toolTip) { /* KHTML (Konqueror/Safari) provides the same * information in window.event and DOM evt. * I choose to use evt if available. */ var ie_x = document.body.scrollLeft || document.documentElement.scrollLeft || 0; var ie_y = document.body.scrollTop || document.documentElement.scrollTop || 0; var x, y; if (evt) { /* evt all Mozilla and IE window.event for open at mouuse. */ x = (typeof evt.pageX != "undefined")? evt.pageX: (evt.clientX + ie_x); y = (typeof evt.pageY != "undefined")? evt.pageY: (evt.clientY + ie_y); } else { /* IE when tracking mouse */ x = window.event.clientX + ie_x; y = window.event.clientY + ie_y; } /* Code for this demo only */ document.options.coordinates.value = "X: " + x + ", Y: " + y; /* Adjust position for screen right and bottom screen edge */ x = fitWindowWidth(x + Xoffset); y = fitWindowHeight(y + Yoffset); /* Move tip into position */ toolTip.style.left = x + 'px'; toolTip.style.top = y + 'px'; } }//eof trackMouse
/* Get toolTip X,Y when not tracking mouse */ function getCoordinates(obj) { if (useLinkHeight) Yoffset += obj.offsetHeight; //If flag, adjust Yoffset by target height var xy = getObjectUpperLeft(obj); /* Adjust position for screen right and bottom screen edge */ var x = fitWindowWidth(xy.x + Xoffset); var y = fitWindowHeight(xy.y + Yoffset); /* return object with coordinates as properties */ return {Xoffset: x, Yoffset: y}; }//eof getCoordinates
function getObjectUpperLeft(obj){ var isIE = (navigator.userAgent.toLowerCase().indexOf("msie") != -1); var x = obj.offsetLeft; var y = obj.offsetTop; /* Calculate page X,Y of upper left corner of element where toolTip is to be shown */ obj = obj.offsetParent; while (obj) { x += obj.offsetLeft; y += obj.offsetTop; if (typeof obj.clientLeft != "undefined" && obj.tagName != "BODY") { /*MS IE doesn't include borders in offset values; these are obtained with clientLeft and Top and added in*/ x += obj.clientLeft; y += obj.clientTop; } if (obj.tagName == "HTML") break; //KHTML KDE has an unidentified object above html obj = obj.offsetParent; }//endwhile return {x:x, y:y}; }//eof getObjectUpperLeft
/* Determine page offset at bottom of screen (it's different than window height) Here the pixles the page has been scrolled up is added to window heigth */ function getBottomPagePos() { var nBottom; if (typeof window.scrollY != "undefined" ) { //NN6+ FireFox, Mozilla etc. nBottom = window.innerHeight + window.scrollY; } else if (typeof window.pageYOffset != "undefined") { //NN4 still in NN6 + but NN6 and Mozilla added scrollY nBottom = window.innerHeight + window.pageYOffset; } else if (document.documentElement && document.documentElement.clientHeight){ //document.compatMode == "CSS1Compat" that is IE6 standards mode nBottom = document.documentElement.clientHeight + document.documentElement.scrollTop; } else if (document.body && document.body.clientHeight) { //document.compatMode != "CSS1Compat" that is quirks mode IE 6 or IE < 6 and Mac IE nBottom = document.body.clientHeight + document.body.scrollTop; } return nBottom; }//eof getBottomPagePos
/* Determine page offset at right of screen (it's different than window width) Here the pixles the page has been scrolled left is added to window width */ function getRightPagePos() { var nRight; if (typeof window.srcollX != "undefined") { //"NN6+ FireFox, Mozilla etc." nRight = window.innerWidth + window.scrollX; } else if (typeof window.pageXOffset != "undefined") { //NN4 code still in NN6 + but scrollX was added nRight = window.innerWidth + window.pageXOffset; } else if (document.documentElement && document.documentElement.clientWidth){ //document.compatMode == "CSS1Compat" that is IE6 standards mode" nRight = document.documentElement.clientWidth + document.documentElement.scrollLeft; } else if (document.body && document.body.clientWidth) { //document.compatMode != "CSS1Compat" that is quirks mode IE 6 or IE < 6 and Mac IE nRight = document.body.clientWidth + document.body.scrollLeft; } return nRight; }//eof getRightPagePos
function getTopPagePos() { var nTop; if (typeof window.scrollY != "undefined" ) { //NN6+ FireFox, Mozilla etc. nTop= window.scrollY; } else if (typeof window.pageYOffset != "undefined") { //NN4 still in NN6 + but NN6 and Mozilla added scrollY nTop = window.pageYOffset; } else if (document.documentElement && document.documentElement.scrollTop){ //document.compatMode == "CSS1Compat" that is IE6 standards mode nTop = document.documentElement.scrollTop; } else if (document.body && document.body.scrollTop) { //document.compatMode != "CSS1Compat" that is quirks mode IE 6 or IE < 6 and Mac IE nTop = document.body.scrollTop; } return nTop; }//eof getTopPagePos
function getLeftPagePos() { var nLeft; if (typeof window.srcollX != "undefined") { //"NN6+ FireFox, Mozilla etc." nLeft = window.scrollX; } else if (typeof window.pageXOffset != "undefined") { //NN4 code still in NN6 + but scrollX was added nLeft = window.pageXOffset; } else if (document.documentElement && document.documentElement.scrolLeft){ //document.compatMode == "CSS1Compat" that is IE6 standards mode" nLeft = document.documentElement.scrollLeft; } else if (document.body && document.body.scrollLeft) { //document.compatMode != "CSS1Compat" that is quirks mode IE 6 or IE < 6 and Mac IE nLeft = document.body.scrollLeft; } return nLeft; }//eof getLeftPagePos
/* Determine best page X that keeps object in window. If object doesn't fit adjust to left edge ot window. Compare object X coordinate to max X not going out of window and use left most. Then check object X is not past left most visible page coordinate. */ function fitWindowWidth(tipX) { //Don't go past right edge of window var rightMaxX = getRightPagePos() - (toolTip.offsetWidth + 16); //16 for scrollbar tipX = (rightMaxX < tipX) ? rightMaxX : tipX; //But, don't go past left edge of window var leftMinX = getLeftPagePos(); tipX = (tipX < leftMinX) ? leftMinX : tipX; return tipX; }//eof fitWindowWidth
/* Compare max acceptable page offset to toolTip X and return smallest */ function fitWindowHeight(tipY) { //Don't go below bottom of window. Put above target if moved. var bottomMaxY = getBottomPagePos() - (toolTip.offsetHeight); tipY = (bottomMaxY < tipY ) ? tipY - (Yoffset + toolTip.offsetHeight) : tipY; //But, don't go past the top of window var topMinY = getTopPagePos(); tipY = (tipY < topMinY) ? topMinY : tipY; return tipY }//eof fitWindowHeight
/* Create a reference to toolTip container */ function initTip() { if (document.getElementById){ toolTip = document.getElementById("tipDiv"); } else if (document.all) { toolTip = document.all.tipDiv; } else if (document.layers) { toolTip = document.layers.tipDiv; } else { toolTip = null; } }//eof initTip /* End of toolTip specific code */
/* Functions specific to this demo and not a normal part of toolTips */ function checkOptionSettings(num) { Xoffset = isNaN(parseInt(document.options.xoffset.value))?0:parseInt(document.options.xoffset.value); if (num < 5){ useLinkHeight = document.options.theight.checked; toolTip.style.width = "160px"; toolTip.style.textAlign = textAlign; } else { Xoffset = Math.max(Xoffset, 20); useLinkHeight = false; toolTip.style.width = "360px"; toolTip.style.textAlign = "left"; } Yoffset = isNaN(parseInt(document.options.yoffset.value))?0:parseInt(document.options.yoffset.value); openAtMouse = document.options.open.checked; followMouse = document.options.tracking.checked; displayTime = isNaN(document.options.opendelay.value) ? 0 : document.options.opendelay.value ; hideTime = isNaN(document.options.closedelay.value) ? 0 : document.options.closedelay.value; autoCloseTime = isNaN(document.options.autoclose.value) ? 0 : document.options.autoclose.value; } //eof checkOptionSettings
function resetMouseOptionDisplay(){ if (followMouse) { document.options.coordinates.value = 'Tracking Suspended'; } else if (openAtMouse) { document.options.coordinates.value = 'Open at mouse'; } } //eof resetMouseOptionDisplay
/* The check boxes are mutually exclusive and can be all off, thus radio buttons where not used. Displayed text changes according to which boxes are checked. */ function handleCheckBoxes(obj) { switch (obj.value){ case "open": //open at mouse if (obj.checked) { obj.form.tracking.checked = false; if (obj.form.theight.checked){ obj.form.theight.checked = false; obj.form.yoffset.value = '20'; } obj.form.coordinates.value = 'Open At Mouse'; } else if (!obj.form.tracking.checked) { obj.form.coordinates.value = 'Tracking Off'; } break; case "tracking": //track mouse if (obj.checked) { obj.form.open.checked = false; if (obj.form.theight.checked){ obj.form.theight.checked = false; obj.form.yoffset.value = '20'; } obj.form.coordinates.value = 'Tracking On'; } else if (!obj.form.open.checked) { obj.form.coordinates.value = 'Tracking Off'; } break; case "theight": //use element offset height if (obj.checked) { obj.form.open.checked = false; obj.form.tracking.checked = false; obj.form.coordinates.value = 'Tracking Off'; obj.form.yoffset.value = "0"; } else { obj.form.yoffset.value = '20'; } break; } }//eof handleMouseRadios
window.onload = initTip; window.onunload = clearTimers;