jQuery 윤방 효과 구현(二) - 플러그인 구현

개편
앞의 글(jQuery 라운드 효과 실현(一)-기초)은 어떻게 jquery로 간단한 jquery 라운드 효과를 실현하는지 설명했다. 기본적인 기능은 이미 실현되었고 효과는 만족스러워 보인다. 유일하게 부족한 것은 라운드 효과가 필요할 때마다 코드를 복사하여 붙여야 한다는 것이다.만약에 일부 부분을 수정해야 한다(예를 들어 윤방할 때의 애니메이션 효과, 전편에서 사용한 것은 jquery의 페이드 페이드 효과이고 슬라이딩 효과로 바꾸면 js 코드를 수정하는 것이 불가피하다). 그러면 js 코드를 수정해야 한다. 내가 쓴 jquery 윤방 효과의 js 코드에 익숙하지 않은 프로그래머에게 이런 js 코드를 수정하는 것은 정말 어렵다.윤방 플러그인이 실현하고자 하는 목표 중 하나는 플러그인을 유연하게 설정할 수 있다는 것이다. (본 글의 플러그인뿐만 아니라) 프로그래머는 소량의 코드만 쓰면 풍부한 기능을 실현할 수 있다. 이것은 당연히 좋은 일이다.이 글의 윤방 플러그인의 html과 css 부분은 프로그래머가 직접 작성해야 하고 효과를 실현하는 js는 소량의 작성만 하면 된다.
플러그인 구현
(function($, window, document) {
	//---- Statics
	var DEFAULT_ANIMATE_TYPE = 'fade', 
		ARRAY_SLICE = [].slice,
		ARRAY_CONCAT = [].concat
		;
	
	//---- Methods
	function concatArray() {
		var deep = false,
			result = [];
		if(arguments.length > 0 && 
				arguments[arguments.length - 1] === true) {
			deep = true;
		}
		for(var i = 0; i < arguments.length; i++) {
			if(!!arguments[i].length) {
				if(deep) {
					for(var j = 0; j < arguments[i].length; j++) {
						//recursive call
						result =  ARRAY_CONCAT.call(result, 
								concatArray(arguments[i][j], true));
					}
				} else {
					result = ARRAY_CONCAT.call(result, arguments[i]);
				}
			} else if(i != arguments.length - 1 || 
					(arguments[arguments.length - 1] !== true &&
							arguments[arguments.length - 1] !== false)) {
				result.push(arguments[i]);
			}
		}
		return result;
	}

	//----- Core
	$.fn.extend({
		zslider: function(zsliderSetting, autoStart) {
			var itemLenght = 0,
				currItemIndex = 0,
				started = false,
				oInterval = {},
				setting =  {
					intervalTime: 3000,
					step: 1,
					imagePanels: $(),
					animateConfig: {
						atype: 'fade',
						fadeInSpeed: 500,
						fadeOutSpeed: 1000
					},
					panelHoverStop: true,
					ctrlItems: $(),
					ctrlItemActivateType: 'hover' || 'click',
					ctrlItemHoverCls: '',
					flipBtn: {},
					panelHoverShowFlipBtn: true,
					callbacks: {
					    animate: null
					}
				},
				that = this
				;
			
			//core methods
			var slider = {
					pre: function() {
						var toIndex = itemLenght + 
							(currItemIndex - setting.step) % itemLenght;
						slider.to(toIndex);
					},
					next: function() {
						var toIndex = (currItemIndex + setting.step) % itemLenght;
						slider.to(toIndex);
					},
					to: function(toIndex) {
						//handle the index value
						if(typeof toIndex === 'function') {
							toIndex = toIndex.call(that, concatArray(setting.imagePanels, true), 
										concatArray(setting.ctrlItems, true),
											currItemIndex, step);
						}
						if(window.isNaN(toIndex)) {
							toIndex = 0;
						}
						toIndex = Math.round(+toIndex) % itemLenght;
						if(toIndex < 0) {
							toIndex = itemLenght + toIndex;
						}
						
						var currentPanel = setting.imagePanels.eq(currItemIndex),
						toPanel = setting.imagePanels.eq(toIndex),
						currrntCtrlItem = setting.ctrlItems.eq(currItemIndex)
						toCtrlItem = setting.ctrlItems.eq(toIndex)
						;
						if(!setting.callbacks.animate || 
								setting.callbacks.animate.call(that, 
										concatArray(setting.imagePanels, true), 
											concatArray(setting.ctrlItems, true),
												currItemIndex, toIndex) === true) {
							currrntCtrlItem.removeClass(setting.ctrlItemHoverCls);
							toCtrlItem.addClass(setting.ctrlItemHoverCls);
							
							toPanel.fadeIn(setting.animateConfig.fadeInSpeed);
							currentPanel.fadeOut(setting.animateConfig.fadeOutSpeed);
						}
						
						//set the current item index
						currItemIndex = toIndex;
					},
					start: function() {
						if(!started) {
							started = true;
							oInterval = 
								window.setInterval(slider.next, setting.intervalTime);
						}
					},
					stop: function() {
						if(started) {
							started = false;
							window.clearInterval(oInterval);
						}
					},
					isStarted: function() {
						return started;
					}
			};
			function initData() {
				if(zsliderSetting) {
					var temp_callbacks = zsliderSetting.callbacks;
					
					$.extend(setting, zsliderSetting);
					$.extend(setting.callbacks, temp_callbacks);
					
					itemLenght = setting.imagePanels.length;
				}
				//convert to the jquery object
				setting.imagePanels = $(setting.imagePanels);
				setting.ctrlItems = $(setting.ctrlItems);
				setting.flipBtn.container = $(setting.flipBtn.container);
				setting.flipBtn.preBtn = $(setting.flipBtn.preBtn);
				setting.flipBtn.nextBtn = $(setting.flipBtn.nextBtn);
			}
			function initLook() {
				//show the first image panel and hide other
				setting.imagePanels.hide();
				setting.imagePanels.filter(':first').show();
				//activate the first control item and deactivate other
				setting.ctrlItems.removeClass(setting.ctrlItemHoverCls);
				setting.ctrlItems.filter(':first').addClass(setting.ctrlItemHoverCls);
				$(that).css('overflow', 'hidden');
				if(setting.panelHoverShowFlipBtn) {
					showFlipBtn(false);
				}
			}
			function initEvent() {
				$(concatArray(setting.imagePanels, 
						setting.flipBtn.preBtn, setting.flipBtn.nextBtn, true)).hover(function() {
					if(setting.panelHoverStop) {
						slider.stop();
					}
					if(setting.panelHoverShowFlipBtn) {
						showFlipBtn(true);
					}
				}, function() {
					slider.start();
					if(setting.panelHoverShowFlipBtn) {
						showFlipBtn(false);
					}
				});
				if(setting.ctrlItemActivateType === 'click') {
					setting.ctrlItems.unbind('click');
					setting.ctrlItems.bind('click', function() {
						slider.to($(this).index());
					});
				} else {
					setting.ctrlItems.hover(function() {
						slider.stop();
						slider.to($(this).index());
					}, function() {
						slider.start();
					});
				}
				setting.flipBtn.preBtn.unbind('click');
				setting.flipBtn.preBtn.bind('click', function() {
					slider.pre();
				});
				setting.flipBtn.nextBtn.unbind('click');
				setting.flipBtn.nextBtn.bind('click', function() {
					slider.next();
				});
			}
			function init() {
				initData();
				
				initLook();
				
				initEvent();
			}
			
			function showFlipBtn(show) {
				var hasContainer = setting.flipBtn.container.length > 0,
					eles;
				eles = hasContainer ? setting.flipBtn.container :
					//to the dom array:
					/*ARRAY_CONCAT.call(ARRAY_SLICE.apply(setting.flipBtn.preBtn), 
							ARRAY_SLICE.apply(setting.flipBtn.nextBtn));*/
					concatArray(setting.flipBtn.preBtn, 
									setting.flipBtn.nextBtn, true);
				if(show) {
					$(eles).show();
				} else {
					$(eles).hide();
				}
			}
			
			init();
			if(arguments.length < 2 || !!autoStart){
				slider.start();
			}
			return slider;
		}
	});
})(jQuery, window, document);

zslider 플러그인 다운로드 주소
github:https://github.com/ricciozhang/zslider_v1
csdn:http://download.csdn.net/detail/qq791967024/9098081

좋은 웹페이지 즐겨찾기