/* * Tooltip - jQuery plugin for simple tooltip showing over HTML elements * Revision 0.7b * * Copyright (c) 2008 Berny Cantos a.k.a. xPheRe * * Licensed under the GPL license: * http://www.gnu.org/licenses/gpl.html * * If this library suits your needs and */ ;(function($){ $.tooltip = { /* Default tooltip settings */ defaults: { 'class': 'tooltip', // Tooltip class added to destiny HTML element css: {}, // CSS applied to destiny HTML element event: 'mouseover', // Event the tooltip must respond to smart: false, // If the tooltip content is generated in a 'smart' way track: true, // If the tooltip must follow mouse position offset: {x: 12, y: 18} // Offset from current mouse position, only applied if track set to true }, /* * Shortcut to setup default settings * Example: * $.tooltip.setup({event: 'click', track: 'false'}); */ setup: function(opt){ $.extend($.tooltip.defaults, opt) } } /* The TIP object */ var tip = function(src, opt) { var self = this; var html = ''; src = $(src); /* Use metadata plugin (if loaded) to modify local options */ if($.metadata) { opt = $.extend({}, opt, src.metadata().tooltip) } /* Tries to generate the content from the HTML element attributes */ if(opt.smart) { /* Tooltip title from 'title' attribute */ if(!opt.title){ opt.title = src.attr('title') } /* Tooltip text from 'alt' attribute */ if(!opt.text){ opt.text = src.attr('alt') } /* url from 'href' attributes. Great for link tags */ if(!opt.href){ opt.href = src.attr('href') } } /* Generates HTML content */ var html = ''; if(opt.title) { html += '
'+opt.title+'
' } if(opt.text) { html += '
'+opt.text+'
' } if(opt.href) { html += '
'+opt.href+'
' } /* If no content where generated, no tooltip is created */ if(html == ''){ delete this; return } /* Removes attributes disabling default tooltips from the browser */ src .removeAttr('title') .removeAttr('alt') $.data(src, 'tooltip', self) self.dst = opt.dst; src .bind(opt.event+'.tooltip', over) .bind('mouseout.tooltip', out) .bind('focus.tooltip', over) .bind('blur.tooltip', out) .bind('click.tooltip', hide) /* Destroy existent timers */ function destroy_timers() { if(self.timein){ clearTimeout(self.timein); delete self.timein } if(self.timeout){ clearTimeout(self.timeout); delete self.timeout } } /* Called when the 'show tooltip' event is raised */ function over(ev){ destroy_timers(); if(self.st == out){ return } self.st = over; /* No destiny defined, must create a new HTML element */ if(!self.dst) { self.dst = $('
') .appendTo(document.body) .css({visibility:'hidden'}) } self.ev = ev; /* Wait some time and show the tooltip */ self.timein = setTimeout(show, opt['in'] || 0) } /* Shows the tooltip */ function show(){ destroy_timers(); /* No destiny, no showing */ if(!self.dst) { return } /* Modifies tooltip CSS and content */ self.dst .addClass(opt['class']) .css(opt.css) .html(html); /* If a duration is defined */ if(opt.duration > 0) { self.timein = setTimeout(hide, opt.duration) } /* Keep track of mouse position if 'track' is activated */ if(opt.track) { self.dst .css({ position:'absolute', visibility:'visible' }) src .bind('mousemove.tooltip', move); $('body') .bind('click.tooltip', hide) } /* Calculates width and height */ self.w = self.dst.width(); self.h = self.dst.height(); /* 'on show' callback */ if(opt.onshow){ opt.onshow.apply(self.dst) } if(opt.track){ move() } } /* Called when the tooltip must hide */ function out(){ destroy_timers(); if(self.st != over){ return } /* Wait some time and hides the tooltip */ self.timeout = setTimeout(hide, opt['out'] || 0) } /* Hides the tooltip */ function hide() { destroy_timers(); /* Unbind all events in body from the tooltip namespace */ $('body').unbind('.tooltip'); /* Unbind mousemove events */ $('src').unbind('mousemove.tooltip'); /* No destiny, no hiding */ if(!self.dst) { return } /* Clear destiny contents */ self.dst.empty(); /* 'on hide' callback */ if(opt.onhide){ opt.onhide.apply(self.dst) } /* If destiny was dinamicly created, destroy it */ if(self.dst != opt.dst) { self.dst.remove(); delete self.dst } } /* Moves the tooltip to follow the cursor */ function move(ev){ if(!ev){ ev = self.ev } else { self.ev = ev} if(!self.dst) { return } var p = { x: ev.pageX + opt.offset.x, y: ev.pageY + opt.offset.y, w: self.w, h: self.h } w = window; var v = { x: w.scrollX, y: w.scrollY, w: w.innerWidth - 20/*(w.scrollMaxY > 0 ? 30 : 20)*/, h: w.innerHeight - 20/*(w.scrollMaxX > 0 ? 20 : 10)*/ }; /* Better not to go offscreen */ if(p.x + p.w > v.x + v.w) { p.x = v.x + v.w - p.w } if(p.y + p.h > v.y + v.h) { p.y = ev.pageY - p.h - opt.offset.y } if(p.x < v.x){ p.x = v.x } if(p.y < v.y){ p.y = v.y } self.dst.css({top:p.y, left:p.x}) } } /* * Change tooltip local settings * Example: * $('a').tooltip('setup', {event: 'click'}) */ function setup(){ return this.each(function(){ t = $.data(this, 'tooltip'); if(t){$.extend(t.opt, opt)} return this }) } /* * Removes tooltip * Example: * $('div').tooltip('remove') */ function remove(){ return this .unbind('.tooltip') .removeData('tooltip') } /* * Creates a tooltip * Example: * $('div').tooltip('create') */ function create(opt){ remove.apply(this); opt = $.extend({}, $.tooltip.defaults, opt); return this.each(function(){ new tip(this, opt); }); } /* * Extends jQuery functions */ $.fn.tooltip = function(a, o) { /* If called with only one non-string parameter (or none), it assumes 'create' by default */ if(!o && (typeof a != 'string')) { o = a; a = 'create' } /* Call the selected function */ return (f = ({ setup: setup, remove: remove, create: create })[a]) && f.apply(this, [o]) } })(jQuery);