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.
-
2\$\begingroup\$ for future reference: Please include the code in the question, not a link to it \$\endgroup\$seand– seand2012年01月18日 19:56:31 +00:00Commented Jan 18, 2012 at 19:56
-
\$\begingroup\$ I'm kind of curious why you picked a tooltip plugin, with so many of those (e.g. qTip) already in existence? \$\endgroup\$Kato– Kato2012年01月26日 15:40:43 +00:00Commented Jan 26, 2012 at 15:40
1 Answer 1
You ask:
- 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?
A:
No. If you filter out any "extra" settings and someone comes along to extend your code they will have trouble if they want to add extra settings. There doesn't seem to be any reason to remove them.
Also on this point
settings = $.extend(defaultSettings,settings);
is normally
settings = $.extend({}, defaultSettings, settings || {});
This allows settings to be optional and defaultSettings won't be overridden.
I would also move var defaultSettings
outside your $.fn.wTip
function (but still in your closure (function($){
) this will mean its not created every time.
While it is not necessary, I would return this
in your eventScheduler
class
function eventScheduler()
{
return this;
}
Its easier to understand that it is a class. (Also most class are Capitalized but thats just a style).
Overall I would say you have a nice clean coding style.
-
\$\begingroup\$ Thanks man, those are great tips. I also moved the $('body').append(tip.generate()); call into the generate function itself, which seemed to make more sense to me as well. \$\endgroup\$Rob– Rob2012年01月23日 00:48:33 +00:00Commented Jan 23, 2012 at 0:48