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让进度更平滑

posted @ 2011-09-26 15:39  MrPrime  阅读(4421)  评论(3编辑  收藏  举报