感觉自己以前写得那些jquery小插件,组织形式不是很好。看到jquery官网有一篇关于 jquery plugin最佳实践的文章。 觉得有所收获,就写了个progressbar插件来做个练习。
代码如下,逻辑很简单:
/**
* jquery progressbar plugin
* author: Andrew
* date: 2011-09-25
* version: 1.0.0
*/
;(function($) {
// all plugin method
// methods 管理plugin所需要的所有方法
var methods = {
// 初始化进度条
init: function(options) {
var opts = $.extend({}, $.fn.progressbar.settings, options);
return this.each(function() {
var data = $(this).data('progressbar');
// check whether plugin has been init
if(!data) {
var percent = '0%';
if(opts.value > opts.min) {
percent = Math.round( (opts.value - opts.min) / (opts.max - opts.min) * 100 ) + '%';
}
var $barCon = $(this).css({
width: opts.width,
height: opts.height
}).addClass('progressbar').data('progressbar', {
min: opts.min,
max: opts.max,
value: opts.value
});
var $bar = $('<div />').css({
width: percent,
height: opts.height
}).addClass('progressbar-value').appendTo($barCon);
// bind custom event with namespace '.progressbar'
$barCon.bind('change.progressbar', opts.change)
.bind('complete.progressbar', opts.complete);
}
});
},
// 获取最小值
getMin: function() {
return this.data('progressbar').min;
},
// 获取最大值
getMax: function() {
return this.data('progressbar').max;
},
// 获取当前值
getValue: function() {
return this.data('progressbar').value;
},
// 设置当前值
setValue: function(val) {
var min = methods.getMin.apply(this),
max =methods.getMax.apply(this);
if(val < min) val = min;
if(val > max) val = max;
this.data('progressbar').value = val;
var percent = Math.round( (val - min) / (max - min) * 100 ) + '%';
this.find('div.progressbar-value').css('width', percent);
var baseData= this.data('progressbar');
var changeEvent = $.extend({}, baseData, {
type: 'change.progressbar'
});
// 触发change回调
this.trigger(changeEvent);
// 如果完成了 触发complete回调
if(val == max) {
var completeEvent = $.extend({}, baseData, {
type: 'complete.progressbar'
});
this.trigger(completeEvent);
}
}
};
// 配置项 或者 方法名
$.fn.progressbar = function(method) {
if(methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call( arguments, 1 ));
} else if($.isPlainObject(method)) {
return methods.init.apply(this, arguments);
} else {
$.error('progressbar plugin don not support method: ' + method + ', please check');
}
};
// default settings
$.fn.progressbar.settings = {
min: 0, // 最小值
max: 100, // 最大值
value: 0, // 当前值
height: 30, // 进度条的高度
width: 200, // 进度条的宽度
change: function(event) {}, // 值改变时的回调
complete: function(event) {} // 达到最大值时的回调
};
})(jQuery);
主要是有以下几点值得提一下:
-
methods对象把所有plugin要用的方法都合理的组织了起来,通过一个入口函数$.fn.progressbar来处理,这样plugin的结构看起来就很清晰了。
-
在处理plugin event时,带上namespace,例如像这样:'eventName.myPluginName',这样就能避免一不小心与DOM的event有冲突。
-
利用jquery的data方法来保存plugin的状态,例如判断plugin是否已经初始化等。
-
最后一点,就是防止全局作用域污染,用(function($) { //your code })(jQuery);
以下是我的jsFiddle示例,略有改进和更新
-
增加了start事件
-
通过animation让进度更平滑