Tooltip con efecto usando jQuery. En un artículo anterior se explicó como hacer un tooltip usando únicamente CSS. Ahora vamos a hacer lo mismo usando jQuery.
Lo bueno de usar jQuery es que nos permite realizar efectos visuales más atractivos. A lo largo de este post vamos a crear un plugin jQuery cuyo objetivo será mostrar un tooltip cuando pasemos con el ratón por encima de ciertos enlaces.
HTML
La estructura de código HTML necesaria es la siguiente:
<div class="tooltip-wrapper">
<a href="" class="tooltip-trigger">Enlace</a>
<div class="tooltip">Contenido del tooltip</div>
</div>
El elemento con la clase .tooltip es el que contiene la información a mostrar. Estará oculto por defecto y tendrá posición absoluta.
El elemento .tooltip-wrapper es un elemento con posición relativa, lo cual permitará ser la referencia de posición para el elemento .tooltip.
Por último el elemento .tooltip-trigger será el elemento que detectará la posición del ratón. Cuando el ratón esté encima de este elemento el tooltip será visible.
El código CSS del elemento .tooltip es el siguiente:
.tooltip{
font-size: .8em;
color: #fff;
display:none;
background: #000;
border:1px solid #ccc;
padding:5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
Nota: He usado las propiedades CSS3 de redondeado de bordes implementadas por los navegadores Firefox y Safari/Chrome, por lo que en caso usar Internet Explorer se visualizará una caja normal.
Javascript
Lo que vamos a hacer es ayudarnos de los eventos mouseover y mouseout para mostrar y ocultar el tooltip.
Mouseover
Primero resetearemos el estado del tooltip (en caso de que ya lo hayamos mostrado)
Segundo lo haremos visible modificando su opacidad y lo desplazaremos un poco hacia arriba.
Por último si se produce otra vez el evento mouseover y el tooltip ya está visible o está en proceso ignoraremos dicho evento.
Mouseout
Cuando se produzca este evento iniciaremos un temporizador para evitar que el tooltip desaparezca repentinamente si accidentalemnte movemos el raton fuera del elemento.
Si se produce el evento y el temporizador está en marcha lo resetearemos.
Cuando el temporizador finalice modificaremos la opacidad del tooltip para ocultarlo mientras lo desplazamos hacia arriba.
Plugin
Empezamos con el plugin jQuery. El plugin se va a llamar 'tooltip' y su estructura, siguiendo el patrón de diseño de plugins de jquery será la siguiente:
(function($){
var opts;
$.fn.tooltip = function(options){
opts = $.extend({}, $.fn.tooltip.defaults, options);
return $(this);
};
// Defaults
$.fn.tooltip.defaults = {};
})(jQuery);
Básicamente lo que hacemos es crear una función anónima y autoejecutable, que toma como argumento la variable jQuery y que dentro de dicha función será llamada $. Esto es muy util porque así podemos evitar conflictos con otros frameworks.
Creamos el plugin usando $.fn.tooltip = function(options){}
Lo cual declara la función tooltip en el espacio de nombres reservado para los plugins de jQuery.
Lo primero que hace esta función es tomar las opciones por defecto y sustituirlas por aquellas que especifiquemos:
opts = $.extend({}, $.fn.tooltip.defaults, options);
De esta forma podemos crear unas opciones por defecto y luego sobre escribirlas facilmente.
Las opciones por defecto están definidas en el espacio de nombres de nuestro plugin:
$.fn.tooltip.defaults = {};
Estas opciones son las siguientes:
$.fn.tooltip.defaults = {
distance: 10, // Distancia que recorre el tooltip hasta aparecer o desaparecer
time: 250, // Tiempo que tarda la animación del tooltip
hideDelay: 250 // Duración del temporizador del tooltip
};
Utilizamores el elemento .tooltip-wrapper como referencia, por tanto el plugin será ejecutado así:
$('.tooltip-wrapper').tooltip();
El código de la función principal del plugin es el siguiente:
Primero establecemos la posición de los elementos: .tooltip-wrapper en relativa y .tooltip en absoluta:
$(this).css('position', 'relative');
$('.tooltip', this).css({'position': 'absolute'});
A continuación modificamos el return de la función por lo siguiente:
return $(this).each(function(){
var hideDelayTimer = null;
// Estado del tooltip
var visible = false; // es visible
var animating = false; // está haciendose visible
// Elemento que activa el tooltip
var trigger = $('.tooltip-trigger', this);
// El tooltip
var tooltip = $('.tooltip', this).css({'opacity': 0});
// Establecemos los eventos mouseover y mouseout para el tooltip y tooltip-trigger
$([trigger.get(0), tooltip.get(0)]).mouseover(function(){
// reseteamos el temporizador
if (hideDelayTimer) clearTimeout(hideDelayTimer);
// Si es visible o está siendo visible lo ignoramos
if(visible || animating){
return;
}else{
animating = true;
// Reseteamos el tooltip
tooltip.css({
top:-50,
display: 'block' // esto muestra el elemento
}).animate({ // animamos la opacidad y la posición
top: '-=' + opts.distance + 'px',
opacity: 0.90
}, opts.time, 'swing', function(){
// Lo marcamos como visible
animating = false;
visible = true;
});
}
}).mouseout(function(){
// Reseteamos el temporizador
if (hideDelayTimer) clearTimeout(hideDelayTimer);
// Creamos el temporizador de nuevo
hideDelayTimer = setTimeout(function(){
hideDelayTimer = null;
// animamos la opacidad y la posición
tooltip.animate({
top: '-=' + opts.distance + 'px',
opacity: 0
}, opts.time, 'swing', function(){
// lo marcamos como no visible
visible = false;
// ocultamos el elemento
tooltip.css('display', 'none');
});
}, opts.hideDelay);
});
El código final es:
(function($){
var opts;
$.fn.tooltip = function(options){
opts = $.extend({}, $.fn.tooltip.defaults, options);
$(this).css('position', 'relative');
$('.tooltip', this).css({'position': 'absolute'});
return $(this).each(function(){
var hideDelayTimer = null;
var visible = false;
var animating = false;
var trigger = $('.tooltip-trigger', this);
var tooltip = $('.tooltip', this).css({'opacity': 0});
$([trigger.get(0), tooltip.get(0)]).mouseover(function(){
if (hideDelayTimer) clearTimeout(hideDelayTimer);
if(visible || animating){
return;
}else{
animating = true;
tooltip.css({
top:-50,
display: 'block'
}).animate({
top: '-=' + opts.distance + 'px',
opacity: 0.90
}, opts.time, 'swing', function(){
animating = false;
visible = true;
});
}
}).mouseout(function(){
if (hideDelayTimer) clearTimeout(hideDelayTimer);
hideDelayTimer = setTimeout(function(){
hideDelayTimer = null;
tooltip.animate({
top: '-=' + opts.distance + 'px',
opacity: 0
}, opts.time, 'swing', function(){
visible = false;
tooltip.css('display', 'none');
});
}, opts.hideDelay);
});
})
};
// Defaults
$.fn.tooltip.defaults = {
distance: 10, // Distancia que recorre el tooltip hasta aparecer o desaparecer
time: 250, // Tiempo que tarda el tooltip en aparecer o desaparecer
hideDelay: 250 // Tiempo que tarda el tooltip en comenzar a desaparecer una vez hemos
};
})(jQuery);
