Realizzare tooltip con jQuery non è semplice, come del resto nulla è semplice quando lo si fa per la prima volta. Scopo di questo articolo è darvi un'idea di base su come procedere. Innanzitutto, un tooltip è un box HTML che compare quando l'utente attiva un controllo sulla pagina. Nel nostro caso andremo ad attivare i nostri tooltip quando l'utente passa col mouse sopra dei link. In seguito, quando l'utente allontana il mouse dal link, il tooltip scomparirà. I nostri link hanno questa struttura:
<a href="#" title="Titolo">...</a>
I tooltip che andremo a creare con jQuery avranno questa struttura:
<span class="tooltip">...</span>
Questi tooltip andranno inseriti nella pagina, riempiti con il contenuto testuale dell'attributo title
(o se vogliamo con un altro tipo di contenuto) e mostrati solo quando l'utente andrà a passare il puntatore sul link. Per prima cosa, assegniamo degli stili CSS ai nostri tooltip:
span.tooltip {
display: block;
width: 150px;
padding: 5px;
background: yellow;
border: 1px solid orange;
font-size: small;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
border-radius: 6px;
position: absolute;
}
Perché abbiamo usato la dichiarazione position: absolute
? Semplicemente perché andremo a mostrare i tooltip vicino ai link a cui si riferiscono. Questa dichiarazione andrà ad interagire con il codice jQuery adibito al calcolo delle coordinate degli elementi.
Il codice jQuery si suddivide in due parti (o fasi): setup ed esecuzione. Ecco il setup:
$(document).ready(function() {
$('p a').each(function() {
var $a = $(this);
var title = $a.attr('title');
$a.removeAttr('title');
var tooltip = $('<span class="tooltip"/>');
tooltip.appendTo('body').hide();
// continua
});
});
Eseguiamo un ciclo each()
su tutti i link contenuti nei paragrafi. Memorizziamo quindi il riferimento all'elemento a
corrente nella variabile $a
per una migliore performance. Quindi facciamo una copia del contenuto dell'attributo title
e poi rimuoviamo l'attributo stesso perchè non vada ad interferire con i nostri tooltip. Questo potrebbe causare dei problemi a livello di accessibilità, ma in questo caso si tratta solo di un esempio. Poi creiamo il nostro elemento con classe tooltip
, lo inseriamo nella pagina e lo nascondiamo.
La seconda fase riguarda l'esecuzione vera e propria dei tooltip:
// continua all'interno di each()
$a.mouseover(function(e) {
var top = e.pageY;
var left = e.pageX;
tooltip.css({
display: 'block',
top: top + 5,
left: left + 5
}).text(title);
});
$a.mouseout(function() {
tooltip.hide(500);
});
Usiamo le coordinate di ciascun link per andare a posizionare il nostro tooltip in modo assoluto. Si noti come abbiamo usato le proprietà pageY
e pageX
dell'oggetto event
. Visualizziamo il nostro tooltip al passaggio del mouse tramite la dichiarazione CSS display: block
e lo nascondiamo tramite il metodo fadeOut
attribuendogli un certo ritardo per creare un effetto di transizione. Un potenziale errore in questo codice è il fatto che ho usato il metodo text()
solo quando il tooltip viene posizionato. Per una migliore efficienza avrei dovuto usarlo all'atto della creazione del tooltip e prima di nasconderlo nella pagina.
Ecco l'esempio in azione.
A questo punto possiamo aggiungere delle animazioni usando il metodo animate()
di jQuery.
L'effetto che vogliamo ottenere è quello di tooltip che si espandono e si contraggono. Per far questo modifichiamo innanzitutto il nostro CSS come segue:
span.tooltip {
display: block;
width: 0px;
padding: 0px;
background: yellow;
border: 1px solid orange;
font-size: small;
-moz-border-radius: 6px;
border-radius: 6px;
position: absolute;
}
Come si può notare, abbiamo impostato padding e larghezza su zero. Questo ci consentirà in seguito, tramite jQuery, di ottenere l'effetto voluto. Il codice jQuery è praticamente identico a quello visto nel precedente post, ad eccezione dell'uso del metodo animate()
:
$(document).ready(function() {
$('p a').each(function() {
var $a = $(this);
var title = $a.attr('title');
$a.removeAttr('title');
var tooltip = $('<span class="tooltip"/>');
tooltip.text(title);
tooltip.appendTo('body').hide();
$a.mouseover(function(e) {
var top = e.pageY;
var left = e.pageX;
tooltip.css({
display: 'block',
top: top + 5,
left: left + 5
}).animate({
width: '150px',
padding: '5px'
}, 'slow');
});
$a.mouseout(function() {
tooltip.animate({
width: '0px',
padding: '0px',
visibility: 'hide'
}, 'slow');
});
});
});
Per prima cosa, quando l'utente passa il mouse sul link, il nostro tooltip viene prima posizionato tramite il metodo css()
e quindi animato espandendone la larghezza fino a 150 pixel e aggiungendo del padding. Per rendere l'effetto più evidente abbiamo impostato la velocità su slow
. Viceversa, quando l'utente allontana il mouse dal link, le dimensioni del tooltip vengono riazzerate e l'intero elemento viene nascosto usando la dichiarazione visibility: 'hide'
. Potete vedere l'effetto finale
qui.
Nota su Internet Explorer
Internet Explorer 8 (e versioni inferiori) sembrano avere dei problemi nell'impostare la visibilità dell'elemento usando le dichiarazioni sopra indicate. Per una maggiore compatibilità cross-browser, si rimuova la dichiarazione visibility: hide
e si aggiunga una funzione di callback al metodo animate()
utilizzando in essa il metodo hide()
.
Per chiudere la nostra panoramica affrontiamo il discorso dei tooltip complessi. Per tooltip complessi si intendono quei tooltip che al loro interno contengono altri elementi HTML e contenuto misto. Nel nostro esempio vedremo come implementare un sistema di anteprima per una galleria di immagini.
Questa volta la struttura dei nostri tooltip appare come segue:
<div class="tooltip">
<img/>
<p>Didascalia</p>
</div>
In questo caso ciascun tooltip avrà al suo interno l'immagine a dimensioni intere e una didascalia testuale. Definiamo subito le regole CSS per la sua visualizzazione:
div.tooltip {
display: block;
width: 450px;
padding: 10px 8px;
background: #eee;
border: 1px solid gray;
font-size: small;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
border-radius: 6px;
position: absolute;
}
div.tooltip img {
display: block;
margin: 0 auto;
}
div.tooltip p {
margin: 0;
padding: 6px 0;
text-align: center;
font-style: italic;
text-transform: uppercase;
font-variant: small-caps;
}
Il posizionamento assoluto dichiarato nel CSS servirà a jQuery per posizionare esattamente il nostro tooltip. Il codice jQuery appare di nuovo diviso in due fasi: setup ed esecuzione. Il setup è il seguente:
$(document).ready(function() {
$('#gallery li a').each(function() {
var $a = $(this);
var title = $a.find('img').attr('alt');
var src = $a.find('img').attr('src');
var tooltip = $('<div class="tooltip"/>');
var img = '<img src="' + src + '" />';
var caption = '<p>' + title + '</p>';
tooltip.html(img + caption);;
tooltip.appendTo('body').hide();
// continua
});
});
Eseguiamo un loop all'interno dei link contenuti nella galleria. Memorizziamo il riferimento al link corrente nella variabile $a
per ottimizzare la performance. A questo punto memorizziamo gli attributi src
e alt
di ciascuna immagine che ci permetteranno, rispettivamente, di creare l'immagine all'interno del tooltip e la sua didascalia. Assembliamo il nostro tooltip tramite il metodo html()
, lo inseriamo nella pagina e lo nascondiamo.
A questo punto possiamo definire la fase di esecuzione vera e propria:
// continua all'interno di each()
$a.mouseover(function(e) {
var top = e.pageY;
var left = e.pageX;
tooltip.css({
display: 'block',
top: top + 5,
left: left + 5
});
});
$a.mouseout(function() {
tooltip.hide(500);
});
Utilizziamo le proprietà pageX
e pageY
dell'oggetto event
per posizionare in modo assoluto il tooltip tramite il metodo css()
. In seguito, quando l'utente allontana il mouse dal link, rimuoviamo il tooltip tramite il metodo fadeOut()
. Per migliorare questo esempio si potrebbe usare la stessa tecnica direttamente sulle immagini. Potete trovare l'esempio completo in questa demo.
Tutti i documenti di esempio sono anche disponibili per il download.