theniteowl
Programmer
Hi All,
This is some code I have not worked on since last April.
It places a tip box on the page in relation to the element it is attached to but it also works to ensure that it never goes off screen by calculating the current element position, size of the screen and scroll position of the viewable window. If the box will go offscreen left or right it works to adjust the position accordingly. If it will go off the bottom of the viewable window it should flip itself to x pixels above the related element instead.
I have had problems getting this to work in anything but quirks mode and have issues with Firefox reporting back numbers I can use when trying to keep the box from going off the bottom of the window.
Please, any experts take a look and tell me if you know how to overcome the issues. Otherwise it is a very nice little tipbox utility.
At my age I still learn something new every day, but I forget two others.
This is some code I have not worked on since last April.
It places a tip box on the page in relation to the element it is attached to but it also works to ensure that it never goes off screen by calculating the current element position, size of the screen and scroll position of the viewable window. If the box will go offscreen left or right it works to adjust the position accordingly. If it will go off the bottom of the viewable window it should flip itself to x pixels above the related element instead.
I have had problems getting this to work in anything but quirks mode and have issues with Firefox reporting back numbers I can use when trying to keep the box from going off the bottom of the window.
Please, any experts take a look and tell me if you know how to overcome the issues. Otherwise it is a very nice little tipbox utility.
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<TITLE></TITLE>
<style type="text/css">
<!--
body div#tipBox {
position:absolute;
z-index:1000;
width:320px;
background:#E5ECF9;
border:1px solid #3366CC;
text-align:left;
padding:5px;
min-height:1em;
color:#000;
font:11px/12px verdana,arial,sans-serif;
}
-->
</style>
<!-- #tipbox {position: absolute; z-index: 100;border: 1pt black solid; background: #FFFFD0; visibility: hidden; font-size:8pt; font-family: "verdana, arial"; color:#000000 } -->
<SCRIPT type=text/JavaScript>
<!--
/*
Future Improvements: Allow for non-disappearing tags or timed-disappearing tags.
Possibly change from altering length of delay for fade (set as speed) to a change in the increment of opacity and
see if it gives a smoother transition.
If box does not fit in either position??? Routine to allow it to stretch sideways up to max width of screen and
then determine if it fits bottom or top?
*/
var tID; //Global variable for delay timer.
var opacityID; //Global variable for opacity timer.
var fadeIn = true; //Set Fade In feature default: true=on, false=off.
var fadeOut = true; //Set Fade Out feature default: true=on, false=off.
var fadeInSpeed = 20; //Default Fade In speed setting.
var fadeOutSpeed = 20; //Default Fade Out speed setting.
var tipWidth = 220;
var scrHeight;
var scrWidth;
var scrLeft=0;
var scrTop=0;
function showObject(e,outtxt,speed,width)
{ //If speed value is passed in it overrides the fadeIn setting and applies the speed value passed in.
//If fadeIn variable is true but no speed passed in it takes default in fadeInSpeed
var fadeSpeed=(speed)?speed:(fadeIn && speed !=0)?fadeInSpeed:false;
if (window.tID) clearTimeout(tID); //Clear any existing timer.
if ( window.opacityID ) clearTimeout(opacityID);
// Get the object based on browser implementation.
if (!e) var e = window.event;
if (e.target) var obj = e.target;
else if (e.srcElement) var obj = e.srcElement;
if (obj.nodeType == 3) var obj = obj.parentNode; // for Safari bug
obj.style.cursor='pointer';
var tipBox = document.getElementById('tipbox');
tipBox.style.width = (width)?width:tipWidth;
tipBox.innerHTML = outtxt;
setPosition(obj,tipBox);
tipBox.style.visibility = "Visible";
tipBox.style.opacity = '.1';
tipFade('in',10,fadeSpeed);
}
function setPosition(obj,tipBox)
{
setScrSize(); // Sets the scrHeight and scrWidth values.
scrollOffset(); //Sets the scrWT and scrWL values (number of pixels screen is scrolled from top and left).
var elL = getOffset(obj, "Left"); //Objects number of pixels from left of screen.
var elT = getOffset(obj, "Top"); //Objects number of pixels from top of screen.
var boxT; //Topmost position to set tip box.
var boxL; //Leftmost position to set tip box.
var scrBL; //Number of pixels from Left box is placed in scrolled window.
//Set leftmost position of tip box.
boxL = (elL <= scrWL)?scrWL:elL;
scrBL = (elL <= scrWL)?scrWL: elL - scrWL;
if (scrBL + tipBox.offsetWidth > scrWidth) boxL -= (scrBL + tipBox.offsetWidth) - scrWidth;
if (boxL < scrWL) boxL = scrWL; //Never let box start before left edge of screen.
elL = boxL;
//Set topmost position of tip box giving preference to below element but setting above if not enough space below.
boxT = elT+obj.offsetHeight;
//##### NOTE: Not flipping to top reliably in Firefox because FireFox is returning scrWidth/scrHeight including scrollbars.
//Test if box will drop below screen level
elT = (tipBox.offsetHeight+boxT-scrWT > scrHeight && boxT-obj.offsetHeight-tipBox.offsetHeight > scrWT)?boxT-obj.offsetHeight-tipBox.offsetHeight:boxT;
if (document.captureEvents) {
tipBox.style.left = elL;
tipBox.style.top = elT;
}
else if ( window.event.clientX ) {
tipBox.style.pixelLeft = elL;
tipBox.style.pixelTop = elT;
}
}
function setScrSizeOLD() {
if( typeof( window.innerWidth ) == 'number' ) { //Non-IE
scrWidth = window.innerWidth;
scrHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { //IE 6+ in 'standards compliant mode'
scrWidth = document.documentElement.clientWidth;
scrHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { //IE 4 compatible
scrWidth = document.body.clientWidth;
scrHeight = document.body.clientHeight;
}
}
function setScrSize() {
if (self.innerWidth) {
scrWidth = document.documentElement.clientWidth;
scrHeight = document.documentElement.clientHeight;
} else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
scrWidth = document.documentElement.clientWidth;
scrHeight = document.documentElement.clientHeight;
} else if (document.body) {
scrWidth = document.body.clientWidth;
scrHeight = document.body.clientHeight;
}
/******* Problems. Only working in quirks mode and the clientHeight property for Firefox returns the ENTIRE height
of the document not just the content height so it still does not bump the tag to the top of the element if it is
dipping below the window. Might have to revert back to self.innerHeight and deal with compensating for the size
of the scrollbar. ******/
var outstr="clientWidth:"+scrWidth+" clientHeight:"+scrHeight;
window.status = outstr;
}
function scrollOffset() {
if( typeof( window.pageYOffset ) == 'number' ) {
scrWT = window.pageYOffset; scrWL = window.pageXOffset;
} else if( document.body ) {
scrWT = document.body.scrollTop; scrWL = document.body.scrollLeft;
} else if( document.documentElement ) {
scrWT = document.documentElement.scrollTop; scrWL = document.documentElement.scrollLeft;
}
}
function getOffset(obj,which) { // Calculate and return the top and left position of tipbox relative to window.
var amount = obj["offset"+which];
obj = obj.offsetParent;
while (obj!=null) {
amount+=obj["offset"+which];
obj = obj.offsetParent;
}
return amount;
}
function hideObject(speed) {
if (speed)
tipFade('out',80,speed);
else {
document.getElementById('tipbox').style.visibility = "hidden";
}
}
function closeTip(speed) {
if (window.tID) clearTimeout(tID); //Clear any existing timer.
if ( window.opacityID ) clearTimeout(opacityID);
var fadeSpeed=(speed)?speed:(fadeOut && speed !=0)?fadeOutSpeed:false;
tID = window.setTimeout("hideObject("+fadeSpeed+")",500);
}
function tipFade(fDir,opac,speed) {
var passed = parseInt(opac);
var newOpac = (fDir == 'in')?parseInt(passed+10):parseInt(passed-10);
var tipBox = document.getElementById('tipbox');
if (newOpac < 80 && newOpac > 0 && speed) {
tipBox.style.opacity = '.'+newOpac;
tipBox.style.filter = "alpha(opacity:"+newOpac+")";
opacityID = window.setTimeout("tipFade('" + fDir + "','"+newOpac+"',"+speed+")",speed);
}
else {
tipBox.style.opacity = (fDir == 'in')?'.80':'.00';
tipBox.style.filter = (fDir == 'in')?"alpha(opacity:80)":"alpha(opacity:00)";
}
}
//-->
</SCRIPT>
</head>
<body>
<DIV id="tipbox" style="VISIBILITY: hidden"></DIV>
<B>Table cells</B><BR>
<TABLE width="100%" border=1>
<TR>
<TD height="100" id="one" align=left bgColor=#ffffff><FONT face="Verdana, Arial, Helvetica" size=1><div onmouseover="showObject(event,'This is the long description for #1',0);" onmouseout="closeTip(200);">Short description #1</div></FONT></TD>
<TD height="100" id="two" onmouseover="showObject(event,'This is the long description for #2',30); this.style.background = '#FFFFD0'" onmouseout="closeTip(); this.style.background = 'white'" align=left bgColor=#ffffff><FONT face="Verdana, Arial, Helvetica" size=1>Short description #2</FONT></TD>
<TD height="100" id=three onmouseover="showObject(event,'This is the long description for #3'); this.style.background = '#FFFFD0'" onmouseout="closeTip(); this.style.background = 'white'" align=left bgColor=#ffffff><FONT face="Verdana, Arial, Helvetica" size=1>Short description #3</FONT></TD>
</TR>
</TABLE>
<BR><BR>
<B>Text within a span tag</B>
<BR>
<SPAN onmouseover="showObject(event,'This is the long description for #1');" onmouseout=closeTip();>Short description #1</SPAN><BR><BR>
<SPAN onmouseover="showObject(event,'This is the long description for #2');" onmouseout=closeTip();>Short description #2</SPAN><BR><BR>
<SPAN onmouseover="showObject(event,'This is the long description for #3');" onmouseout=closeTip();>Short description #3</SPAN><BR><BR>
<BR><BR>
<B>Links</B><BR><A onmouseover="showObject(event,'This is the long description for #1');" onmouseout=closeTip(); href="#">Short description #1</A><BR><BR>
<A onmouseover="showObject(event,'This is the long description for #2',0,300);" onmouseout=closeTip(0); href="#">Short description #2</A><BR><BR>
....................<A onmouseover="showObject(event,'This is the longest description for #3-1234567090',0,300);" onmouseout=closeTip(); href="#">Longer description for #3</A>
<br>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
<br>
<br>
<br>
<br>
<br>
</BODY>
</HTML>
At my age I still learn something new every day, but I forget two others.