Tooltip box

K

Kim

Using the code below am I able to display/hide a tooltip without any
problems, however once the tooltip is displayed its position is fixed
(based on where the mouse first hovered onto the object) and I would
like the tooltip to follow the mouse instead.
What must I change to do this ?


HTML
<a href="#" onMouseOver="showBox('help','text to display')"
onMouseOut="hideBox('help')">text link</a>

JS
function hideLayer(strLayer) {
if (document.getElementById) {
d = document.getElementById(strLayer);
if (d) {
d.style.visibility = 'hidden';
d.style.display = 'none';
}
}
else if (document.all) {
d = eval('document.all[\''+strLayer+'\']');
if (d) {
eval('document.all[\''+strLayer+'\'].style.visibility = \'hidden
\'');
eval('document.all[\''+strLayer+'\'].style.display = \'none\'');
}
}
}
function showLayer(strLayer) {
if (document.getElementById) {
d = document.getElementById(strLayer);
d.style.visibility = 'visible';
d.style.display = 'block';
}
else if (document.all) {
eval('document.all[\''+strLayer+'\'].style.visibility = \'visible
\'');
eval('document.all[\''+strLayer+'\'].style.display = \'block\'');
}
}
function getObj(name) {
if (document.getElementById) {
this.obj = document.getElementById(name);
this.style = document.getElementById(name).style;
}
else if (document.all) {
this.obj = document.all[name];
this.style = document.all[name].style;
}
else if (document.layers) {
this.obj = document.layers[name];
this.style = document.layers[name];
}
return this;
}
document.onmousemove = getMousePosition;
if (!document.all) document.captureEvents(Event.MOUSEMOVE);
var mouse_x = 0;
var mouse_y = 0;
function getMousePosition(e) {
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
mouse_x = e.pageX;
mouse_y = e.pageY;
}
else if (e.clientX || e.clientY) {
mouse_x = e.clientX + (document.documentElement ?
document.documentElement.scrollLeft : document.body.scrollLeft);
mouse_y = e.clientY + (document.documentElement ?
document.documentElement.scrollTop : document.body.scrollTop);
}
}
function showBox(name, msg) {
var x = (mouse_x + 20) + 'px';
var y = (mouse_y + 0) + 'px';
var box = getObj(name);

box.obj.innerHTML = msg;
box.style.position = 'absolute';
box.style.top = y;
box.style.left = x;
showLayer(name);
}
function hideBox(name) {
hideLayer(name);
}
 
R

Robin

Kim said:
Using the code below am I able to display/hide a tooltip without any
problems, however once the tooltip is displayed its position is fixed
(based on where the mouse first hovered onto the object) and I would
like the tooltip to follow the mouse instead.
What must I change to do this ?

There are many libraries to do this so why reinvent the wheel? Anyway,
the simplest change I can see:
var mouse_x = 0;
var mouse_y = 0;

var box = null; // moved to be a global
function getMousePosition(e) {
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
mouse_x = e.pageX;
mouse_y = e.pageY;
}
else if (e.clientX || e.clientY) {
mouse_x = e.clientX + (document.documentElement ?
document.documentElement.scrollLeft : document.body.scrollLeft);
mouse_y = e.clientY + (document.documentElement ?
document.documentElement.scrollTop : document.body.scrollTop);
}

if (box) placeBox();
}
function showBox(name, msg) {
box = getObj(name); // note no 'var' using global
// should really be a check failure here
box.obj.innerHTML = msg;
box.style.position = 'absolute'; placeBox();
showLayer(name);
}

function hideBox(name) {
hideLayer(name); box = null;
}

function placeBox() {
box.style.top = (mouse_x + 20) + 'px';
box.style.left = (mouse_y + 0) + 'px';
}

Robin
 
D

David Mark

Using the code below am I able to display/hide a tooltip without any
problems, however once the tooltip is displayed its position is fixed

Without any problems that you can see.
(based on where the mouse first hovered onto the object) and I would
like the tooltip to follow the mouse instead.

That is so irritating and pointless.
What must I change to do this ?

HTML
<a href="#" onMouseOver="showBox('help','text to display')"
onMouseOut="hideBox('help')">text link</a>

Link goes nowhere? Might navigate to the top of the page in some
browsers.
JS
function hideLayer(strLayer) {
        if (document.getElementById) {

Do not test host object methods in this manner. Use the typeof
operator. Search the group for "isHostMethod".
                d = document.getElementById(strLayer);
                if (d) {
                        d.style.visibility = 'hidden';
                        d.style.display = 'none';
                }
        }
        else if (document.all) {

Here's where the wheels come off.
                d = eval('document.all[\''+strLayer+'\']');
                if (d) {
                        eval('document.all[\''+strLayer+'\'].style.visibility = \'hidden
\'');
                        eval('document.all[\''+strLayer+'\'].style.display = \'none\'');
                }
        }}

Where did you pick that up? If you find yourself using eval, you are
likely off in the weeds.
function showLayer(strLayer) {
        if (document.getElementById) {
                d = document.getElementById(strLayer);
                d.style.visibility = 'visible';
                d.style.display = 'block';
        }
        else if (document.all) {
                eval('document.all[\''+strLayer+'\'].style.visibility = \'visible
\'');
                eval('document.all[\''+strLayer+'\'].style.display = \'block\'');
        }}

Same comments for this virtual duplication.
function getObj(name) {
        if (document.getElementById) {
                this.obj = document.getElementById(name);
                this.style = document.getElementById(name).style;
        }
        else if (document.all) {
                this.obj = document.all[name];
                this.style = document.all[name].style;
        }

No eval this time?
        else if (document.layers) {
                this.obj = document.layers[name];
                this.style = document.layers[name];
        }

Clearly you can lose this branch. It is only for NN4 and makes no
sense in the context of this script.
        return this;}

document.onmousemove = getMousePosition;

It is good practice to declare functions before their first use.
if (!document.all) document.captureEvents(Event.MOUSEMOVE);

That might be the worst object inference (a form of browser sniffing)
I have ever seen. Where did you find this stuff?
var mouse_x = 0;
var mouse_y = 0;
function getMousePosition(e) {
        if (!e) var e = window.event;

e = e || window.event;
        if (e.pageX || e.pageY) {

Wrong. What if both are 0?
                mouse_x = e.pageX;
                mouse_y = e.pageY;
        }
        else if (e.clientX || e.clientY) {

Same here.
                mouse_x = e.clientX + (document.documentElement ?
document.documentElement.scrollLeft : document.body.scrollLeft);

Wrong. The documentElement property is defined in quirks mode. You
should be testing the scrollLeft/Top properties.
                mouse_y = e.clientY + (document.documentElement ?
document.documentElement.scrollTop : document.body.scrollTop);
        }}

Same here.
function showBox(name, msg) {
        var x = (mouse_x + 20) + 'px';
        var y = (mouse_y + 0) + 'px';
        var box = getObj(name);

        box.obj.innerHTML = msg;
        box.style.position = 'absolute';
        box.style.top = y;
        box.style.left = x;
        showLayer(name);}

function hideBox(name) {
        hideLayer(name);

}

I advise you to look into the title attribute. Most browsers will
turn it into a tooltip. Furthermore, search engines, screen readers,
text browsers, etc. will be able to see the content. No script
required. That should save you a lot of trouble.
 
D

David Mark

There are many libraries to do this so why reinvent the wheel? Anyway,
the simplest change I can see:

Name one that is worthwhile. Wheels should be re-invented when
previous attempts fall short.
 
T

Thomas 'PointedEars' Lahn

David said:
Kim said:
return this;}

document.onmousemove = getMousePosition;

It is good practice to declare functions before their first use.

[...]
function getMousePosition(e) {

If so, that practice is at least not supported by language rules: All
declarations are instantiated *before* execution, so order does not matter.

I found that with languages like this some people declare their functions on
the bottom, presumably so that the main code can be edited easier. I
haven't done that yet, but I see no good reason why I shouldn't. Can you
name one?


PointedEars
 
D

David Mark

It is good practice to declare functions before their first use.
[...]
function getMousePosition(e) {

If so, that practice is at least not supported by language rules:  All
declarations are instantiated *before* execution, so order does not matter.

No kidding.
I found that with languages like this some people declare their functionson
the bottom, presumably so that the main code can be edited easier.  I
haven't done that yet, but I see no good reason why I shouldn't.  Can you
name one?

Harder to follow for one.
 
T

Thomas 'PointedEars' Lahn

David said:
Thomas said:
David said:
Kim wrote:
return this;}
document.onmousemove = getMousePosition;
It is good practice to declare functions before their first use.
[...]
function getMousePosition(e) {
If so, that practice is at least not supported by language rules: All
declarations are instantiated *before* execution, so order does not matter.

No kidding.
I found that with languages like this some people declare their functions on
the bottom, presumably so that the main code can be edited easier. I
haven't done that yet, but I see no good reason why I shouldn't. Can you
name one?

Harder to follow for one.

Why is scrolling down harder to follow than scrolling up?
And with an Outline View the issue gets even smaller. *shrug*


PointedEars
 
D

David Mark

On Nov 4, 5:30 pm, Thomas 'PointedEars' Lahn <[email protected]>
wrote:

[snip]
Why is scrolling down harder to follow than scrolling up?

Clearly it isn't. But one can scroll up (or search up or whatever)
knowing that the identifier will be defined above, so it eliminates
the step of looking in the other direction.
And with an Outline View the issue gets even smaller. *shrug*

I never use such things, so I don't know.
 
R

rf

On Nov 4, 5:30 pm, Thomas 'PointedEars' Lahn <[email protected]>
wrote:

[snip]
Clearly it isn't. But one can scroll up (or search up or whatever)
knowing that the identifier will be defined above, so it eliminates
the step of looking in the other direction.

And if they are at the bottom one can scroll down (or search down or
whatever) knowing that the identifier will be defined below, so it
eliminates the step of looking in the other direction.

Also, down is the default search direction in my editors, I don't have to
change it.

When opening a file the overall top level logic is at the top, ready to
read. If the (hopefully static and never changed much) subroutines are at
the top instead one has to search for the overall top level logic. A PITA if
it is not inside a function itself.
 
D

David Mark

On Nov 4, 5:30 pm, Thomas 'PointedEars' Lahn <[email protected]>
wrote:

[snip]


Clearly it isn't.  But one can scroll up (or search up or whatever)
knowing that the identifier will be defined above, so it eliminates
the step of looking in the other direction.

And if they are at the bottom one can scroll down (or search down or

If you put your function declarations after the first use as a rule,
then that should work for you. Seems an odd choice though.

[snip]
 
K

Kim

There are many libraries to do this so why reinvent the wheel? Anyway,
the simplest change I can see:


var box = null; // moved to be a global


if (box) placeBox();


box = getObj(name); // note no 'var' using global
// should really be a check failure here> box.obj.innerHTML = msg;

function placeBox() {
box.style.top = (mouse_x + 20) + 'px';
box.style.left = (mouse_y + 0) + 'px';

}

Robin

Thanks Robin. Works fine.

For the record, I know of two scripts that also can do this (+ a lot
more).
1) www.bosrup.com/web/overlib/
2) http://walterzorn.com/tooltip/tooltip_e.htm
I would never use overLIB as it uses incorrect tables (yes, plural) to
create its tooltip. And I am in fact looking into 2) due to its
extension possibilities.
I used an empty div container as it allows me to apply class/styles to
it without having to hardcode it into the JS function or as a
parameter.

David: Im just a novice JS coder, so when the code works then thats
all that matters. If you can provide an example of these changes you
suggest, please do.
The empty link was just for testing. Im using an image instead and I
dont use the title attribute as my text will most likely be longer
than the what it allows (I have seen it cut off text).
 
T

Thomas 'PointedEars' Lahn

Robin said:

Have you reviewed the source code? I just did. From the looks of it, it is
just another "library" junk put together by novice script monkeys. Browser
sniffing (they call that "Stupidity Check(tm)", how fitting) and unnecessary
eval() to assemble property access syntax are only some of its problems.

As such, it is easily being recommended by script-kiddies, of course.


PointedEars
 
G

Gregor Kofler

Robin meinte:

Yikes. "Extensive" browser sniffing, a thoroughly polluted global
namespace, clumsy string operations for generating innerHTML (which in
turn uses "styling" attributes [1]), eval() all over the place,
inefficient code [2]...

And this whole crap for (usually expendable) tooltips - puhleeze!

Gregor


[1]
txt='<table width="'+o3_width+'" border="0" cellpadding="0"
cellspacing="0" height="'+o3_height+'"><tr><td colspan="3"
height="'+o3_padyt+'"></td></tr><tr><td width="'+o3_padxl+'"></td><td
valign="TOP" width="'+(o3_width-o3_padxl-o3_padxr)+(o3_textfontclass ?
'" class="'+o3_textfontclass : '')+'">'+(o3_textfontclass ? '' :
wrapStr(0,o3_textsize,'text'))+text+(o3_textfontclass ? '' :
wrapStr(1,o3_textsize))+'</td><td width="'+o3_padxr+'"></td></tr><tr><td
colspan="3" height="'+o3_padyb+'"></td></tr></table>';

[2]
// Note: NS4 doesn't like switch cases with vars.
if (ar >= pmCount || ar==DONOTHING) { continue; }
if (ar==INARRAY) { fnMark = 0;
eval(pf+'text=ol_texts['+ar[++i]+'].toString()'); continue; }
if (ar==CAPARRAY) { eval(pf+'cap=ol_caps['+ar[++i]+'].toString()');
continue; }
if (ar==STICKY) { if (pf!='ol_') eval(pf+'sticky=1'); continue; }
if (ar==BACKGROUND) { eval(pf+'background="'+ar[++i]+'"'); continue; }
if (ar==NOCLOSE) { if (pf!='ol_') opt_NOCLOSE(); continue; }
if (ar==CAPTION) { eval(pf+"cap='"+escSglQuote(ar[++i])+"'");
continue; }

[another fifty or sixty lines of if() { eval(); continue; } follow]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top