I've been getting into plugin development for jQuery and my first creation is a tooltip plugin. I've been reading a lot about plugin development especially with the use of JavaScript prototyping. I'm just looking for any tips to further improve my plugin development (only 144 lines of code).
Two questions in particular:
The tooltip accepts "settings" options which I extend the standard jQuery way. Should I be passing only the necessary properties into the "Tip" object for each tooltip rather than the whole settings object, which right now I'm just doing out of convenience and simplicity?
I also pass the event scheduler to the "Tip" object out of convenience, but should I be passing this into the function calls separately rather than keeping it as part of each tooltip object?
demo: http://websanova.com/plugins/tooltips/jquery#wtip
code (also at http://websanova.com/a/plugins/websanova/tooltip/wTip.1.0.js):
/******************************************
* Websanova.com
*
* Resources for web entrepreneurs
*
* @author Websanova
* @copyright Copyright (c) 2012 Websanova.
* @license This wTip jQuery plug-in is dual licensed under the MIT and GPL licenses.
* @link http://www.websanova.com
* @docs http://www.websanova.com/plugins/websanova/tooltip
* @version Version 1.0
*
******************************************/
(function($)
{
$.fn.wTip = function(settings)
{
var defaultSettings = {
color : 'cream', // allow custom with #FFAACC
opacity : 0.8, // opacity level
title : null, // manually set title
fadeIn : 0, // time before tooltip appears in milliseconds
fadeOut : 0, // time before tooltip fades in milliseconds
delayIn : 0, // time before tooltip displays in milliseconds
delayOut : 0, // time before tooltip begins to dissapear in milliseconds
offsetX : 8, // x offset of mouse position
offsetY : 15 // y offset of mouse position
}
var supportedColors = ['red','green','blue','white','black','cream','yellow','orange','plum'];
settings = $.extend(defaultSettings,settings);
return this.each(function()
{
var elem = $(this);
settings.title = settings.title || elem.attr('title') || 'No title set';
var scheduleEvent = new eventScheduler();
var tip = new Tip(settings, scheduleEvent);
$('body').append(tip.generate());
elem
//hover on/off triggers
.hover(function()
{
tip.hover = true;
scheduleEvent.set(function(){ tip.show(); }, settings.delayIn);
},function()
{
tip.hover = false;
if(tip.shown) tip.hide();
})
//move tooltip with mouse poitner
.mousemove(function(e)
{
tip.move(e);
})
//remove title attribute so that we don't have the browser title showing up
.removeAttr('title');
});
}
/**
* Event scheduler class definition
*/
function eventScheduler(){}
eventScheduler.prototype =
{
set: function (func, timeout)
{
this.timer = setTimeout(func, timeout);
},
clear: function()
{
clearTimeout(this.timer);
}
}
/**
* Tip class definition
*/
function Tip(settings, scheduleEvent)
{
this.hover = false;
this.shown = false;
this.settings = settings;
this.scheduleEvent = scheduleEvent;
}
Tip.prototype =
{
generate: function()
{
if(this.tip) return this.tip;
this.tip =
$('<div class="_wTip_holder"><div class="_wTip_outer"><div class="_wTip_bg"></div><div class="_wTip_inner">' + this.settings.title + '</div></div></div>')
.css({display: 'none', position: 'absolute', opacity: this.settings.opacity})
.addClass('_wTip_' + this.settings.color);
return this.tip;
},
show: function()
{
var $this = this;
this.tip.fadeIn(this.settings.fadeIn, function()
{
$this.shown = true;
if(!$this.hover) $this.hide();
});
},
move: function(e)
{
this.tip.css({left: e.pageX + this.settings.offsetX, top: e.pageY + this.settings.offsetY});
},
hide: function()
{
var $this = this;
this.scheduleEvent.set(function()
{
$this.tip.fadeOut($this.settings.fadeOut, function()
{
$this.shown = false;
});
},
this.settings.delayOut);
}
}
})(jQuery);
Any tips or pointers in the right direction appreciated.