Introduction
The idea is to attach one function to each the mouseover
and mouseout
events of the elements that you want to decorate with the tooltip. The function attached to the mouseover
event will create a <div>
element that will host the tooltip message and will be added to the <body>
, whereas the function attached to the mouseout
event will remove the <div>
. Both functions will be packaged inside another function. That is the only function that you will need to use to add the tooltips.
Of course, our <div>
tooltip will have some customizable attribute. In the example that I will show, I decided to limit the list of these attributes to 5 items:
- Message to show
- Fading time
- Background color
- Width
- Border style
I am going to show you the whole code of the function first and then I will comment the parts that -I think- are interesting.
function AddTooltip(objectId,
message,
fadeAfterMs,
cssBackcolor,
cssWidth,
cssBorder) {
const LEFT_FROM_CURSOR = 30;
const TOP_FROM_CURSOR = 5;
const DISTANCE_FROM_RIGHT_BORDER = 20;
const ADDITIONAL_DISTANCE_FROM_BOTTOM = 50;
const BOX_HEIGHT = 50;
if (objectId && message) {
var $tooltip;
$('#' + objectId).on('mouseover', function (e) {
let left = e.originalEvent.pageX + LEFT_FROM_CURSOR;
let top = e.originalEvent.pageY + TOP_FROM_CURSOR;
let width = !cssWidth ? '200px' : cssWidth;
let border = !cssBorder ? '1px solid black' : cssBorder;
let backcolor = !cssBackcolor ? 'aquamarine' : cssBackcolor;
if (left + parseInt(width)- window.pageXOffset > VisibleWidth()) {
left = VisibleWidth() - parseInt(width) - DISTANCE_FROM_RIGHT_BORDER;
}
if (top + BOX_HEIGHT - window.pageYOffset> VisibleHeight() ) {
top = top - BOX_HEIGHT;
}
let s = '<div style="' +
'border:' + border + ';' +
'padding-left:10px;' +
'padding-top:5px;' +
'padding-bottom:5px;' +
'z-index:1;' +
'opacity:0.7;'+
'border-radius:5px;' +
'font-size:small; ' +
'position: absolute;' +
'left:' + left.toString() + 'px;top:' + top.toString() + 'px;' +
'width:' + width + ";" +
'background-color: ' + backcolor + ';' +
'display:inline-block;">' +
message +
'</div>';
$tooltip = $(s).appendTo('body');
$tooltip.attr('id', 'ttp-' + objectId);
if (fadeAfterMs && fadeAfterMs > 0) {
setTimeout(Fade, fadeAfterMs);
}
});
$('#' + objectId).on('mouseout', function (e) {
$($tooltip).remove();
});
}
function Fade() {
$($tooltip).fadeOut(2000, function () {
$($tooltip).remove();
});
}
function VisibleWidth() {
return window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth
|| 0;
}
function VisibleHeight() {
return window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight
|| 0;
}
}
Let's start from the function declaration:
function AddTooltip(objectId,
message,
fadeAfterMs,
cssBackcolor,
cssWidth,
cssBorder)
As expected, the function is called AddTooltip
and has 6 parameters. The first is the id
of the HTML element to whom you want to attach the tooltip box and the second is the message to show. These first two parameters are mandatory. With no element or message, there is really no point in showing a tooltip! The last four parameters are optional. If they are not set, the correspondent attributes of the tooltip box will assume the default values set inside the function.
The fadeAfterMs
parameter is of type Integer
and specifies the number of milliseconds that will elapse between the moment the tooltip box is shown and the moment it will be faded out.
The other optional parameters are of type String
and need to specify the CSS value of the relative property. For example, a value of the parameter cssWidth
is '300px
'.
The mouseover Function
If the mandatory parameters are passed to the function, a new variable that will hold a reference to the tooltip box is created ($tooltip
) and then a function is attached to the mouseover
event.
Inside this function, the initial position of the tooltip box is calculated and some variables will assume either a default value or the value passed through the AddTooltip
parameters.
if (objectId && message) {
var $tooltip;
$('#' + objectId).on('mouseover', function (e) {
let left = e.originalEvent.pageX + LEFT_FROM_CURSOR;
let top = e.originalEvent.pageY + TOP_FROM_CURSOR;
let width = !cssWidth ? '200px' : cssWidth;
let border = !cssBorder ? '1px solid black' : cssBorder;
let backcolor = !cssBackcolor ? 'aquamarine' : cssBackcolor;
Then a string
containing the HTML code of the <div>
is composed and appended to the <body>
tag. Finally, the fading effect is set:
let s = '<div ' +
'style="' +
'border:' + border + ';' +
'padding-left:10px;' +
.
.
'display:inline-block;">' +
message +
'</div>';
$tooltip = $(s).appendTo('body');
$tooltip.attr('id', 'ttp-' + objectId);
if (fadeAfterMs && fadeAfterMs > 0) {
setTimeout(Fade, fadeAfterMs);
}
This is almost all that the mouseover
function does. If the element that has a tooltip added to it is too close to the right side of the window, it might happen that the tooltip box gets over the window and gets cut:
I am not going to explain in detail how this calculation works. It will suffice to say that it involves the measurement of the page scroll and the visible width
of the page:
if (left + parseInt(width)- window.pageXOffset > VisibleWidth()) {
left = VisibleWidth() - parseInt(width) - DISTANCE_FROM_RIGHT_BORDER;
}
A recalculation of top
is also necessary, but unfortunately we do not know the height
of the box
. There are ways to find it but in order to keep this short, I decided to assume that the height
of the box
will never exceed 50 pixels. I don't think this is too much of a limitation because the box is supposed to visualize a tip, not a novel! And it helps in keeping the calculation of the top
simple:
if (top + BOX_HEIGHT - window.pageYOffset> VisibleHeight() ) {
top = top - BOX_HEIGHT;
}
The mouseout Function
This is short and easy: it simply removes the tooltip from <body>
:
$('#' + objectId).on('mouseout', function (e) {
$($tooltip).remove();
});
How to Use the AddTooltip Function
Just specify the element id
and the message!
$(document).ready(function () {
AddTooltip('a-help', 'Do something good....help other people')
AddTooltip('txt-phone', 'In order to avoid phone pranks,
do not give your real number!', 1500, 'pink', '300px')
});
and here is how it looks like:
Happy coding!
History
- 1st February, 2019: Initial version