jquery插件最佳实践之progressbar
感觉自己以前写得那些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让进度更平滑