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;