;(function ($, window, undefined) { var LqSlide; var DEFAULT_OPTIONS; /** * DEFAULT_OPTIONS */ DEFAULT_OPTIONS = { // selector setting listSelector: '.lq-list', itemSelector: 'li', paginationListSelector: '.lq-paginationList', paginationItemSelector: 'li', prevSelector: '.lq-prev', nextSelector: '.lq-next', viewportWrapper: false, fixedToParent: false, // add class name setting cloneClass: 'lq-clone', currentClass: 'lq-current', disableClass: 'lq-disable', // animation setting animate: 'slide', easing: 'swing', speed: 500, vertical: false, fadeZIndexBase: 100, // autoPlay setting autoPlay: false , autoPlayHoverStop: true, autoPlayStopLastItem: false, autoPlayInterval: 5000, autoPlayStartDelay: 0, // option setting start: 0, group: 1, pos_x: 'left', pos_x_fix: 0, loop: true, loopingDisabled: false, listHeightType: 'auto', currentHighlight: true, resizeRefresh: true, resizeTimer: 2000, direction: 'ltr', responsive: false, touch: false, stopOnlast: false, viewportMode: 'start', responsiveItemSize: 0, responsiveWrapSelector: false, itemSizeFixNum: 0 }; /** * LqSlide */ LqSlide = function ($element, options) { var self = this; self.o = $.extend({}, DEFAULT_OPTIONS, options); self.$element = $element; self.$list = (typeof self.o.listSelector == 'string') ? self.$element.find($(self.o.listSelector)) : self.o.listSelector; self.$viewportWrapper = (self.o.viewportWrapper) ? self.$element.find($(self.o.viewportWrapper)) : self.$element; self.$item = (typeof self.o.itemSelector == 'string') ? self.$list.find($(self.o.itemSelector)) : self.o.itemSelector; self.$paginationList = (typeof self.o.paginationListSelector == 'string') ? self.$element.find($(self.o.paginationListSelector)) : self.o.paginationListSelector; self.$paginationItem = (typeof self.o.paginationItemSelector == 'string') ? self.$paginationList.find($(self.o.paginationItemSelector)) : self.o.paginationItemSelector; self.$prevNavi = (typeof self.o.prevSelector == 'string') ? self.$element.find($(self.o.prevSelector)) : self.o.prevSelector; self.$nextNavi = (typeof self.o.nextSelector == 'string') ? self.$element.find($(self.o.nextSelector)) : self.o.nextSelector; self.$allList = self.$paginationList.add(self.$list); self.$allItem = self.$paginationItem.add(self.$item); self.$allListAndNavi = self.$allList.add(self.$prevNavi).add(self.$nextNavi); self.responsiveWrapSelector = self.o.responsiveWrapSelector; self.direction = (self.o.direction == 'ltr') ? 'marginLeft' : 'marginRight'; self.elementSize = (self.o.vertical) ? self.$element.height() : self.$element.outerWidth(true); self.itemSize = self.calcItemSize(); self.sizeProp = (self.o.vertical) ? 'height' : 'width'; self.marginProp = (self.o.vertical) ? 'marginTop' : self.direction; self.itemMargin = self.itemMarginCalc(); self.on_init = (self.o.on_init) ? self.o.on_init : function() {}; self.on_start = (self.o.on_start) ? self.o.on_start : function() {}; self.on_end = (self.o.on_end) ? self.o.on_end : function() {}; self.on_moved = (self.o.on_moved) ? self.o.on_moved : function() {}; self.on_last = (self.o.on_last) ? self.o.on_last : function() {}; self.on_last_item = (self.o.on_last_item) ? self.o.on_last_item : function() {}; self.on_responsive = (self.o.on_responsive) ? self.o.on_responsive : function() {}; self.on_resize = (self.o.on_resize) ? self.o.on_resize : function() {}; self.timer = ''; self.kill = false; self.autoPlayInstance = ''; self.setHoverAction = function() { self.$allListAndNavi.on('mouseover', function(){ self.pause(); }) self.$allListAndNavi.on('mouseleave', function() { self.play(); }); self.kill = false; } self.stop = function () { clearInterval(this.timer); self.$allListAndNavi.off('mouseover mouseleave'); self.kill = true; }; self.pause = function () { clearInterval(this.timer); }; self.play = function () { var autoPlayInterval = (this.o.autoPlayInterval >= 40) ? this.o.autoPlayInterval : 40; this.timer = setInterval(this.autoPlayInstance, autoPlayInterval); if (self.kill) { self.setHoverAction(); } } self.refresh = function() { self.refreshSlider(); } self.refactor = function() { self.reset(); } self.clonePrependNum = 0; self.cloneAppendNum = 0; self.index = self.o.start; self.isMoving = false; self.breakpoint = false; self.resposiveObj = false; self.tempConfig = []; self.tempConfigSet = false; if(self.o.animate === 'fade' || self.$item.length <= 1) { self.o.loop = false; self.o.resizeRefresh = false; self.$item.css({ zIndex: self.o.fadeZIndexBase }); self.$item.eq(self.index).css({ zIndex: self.o.fadeZIndexBase + 1 }); } else { self.o.listHeightType = false; } self.group = self.o.group; self.responsiveItemSize = self.o.responsiveItemSize; self.itemSizeFixNum = self.o.itemSizeFixNum; self.loopingDisabled = self.o.loopingDisabled; self.loop = self.o.loop; self.touch = self.o.touch; self.stopOnlast = self.o.stopOnlast; self.isLastOnScreen = false; self.diff = 0; self._timer = false; self.init(); return self; }; /** * LqSlide.prototype */ (function (fn) { /** * init */ fn.init = function () { var self = this; if (self.o.fixedToParent) { self.$item.css('width' ,self.itemSize); } if (self.responsive) {self.break()} //index self.indexUpdate(self.index); //Loop if (self.loop) { self.makeClone(); } //fade if(self.o.animate === 'fade') { self.$item.hide(); self.$item.eq(self.index).fadeIn(); } //$list style: margin, size self.setListStyle(); //current self.addCurrentClass(); if (self.o.currentHighlight) { self.highlightEffect(); } //autoplay if (self.o.autoPlay) { self.autoPlay(); } //loopingDisabled if (self.loopingDisabled) { self.loopingDisabledFn(); } //resizeRefresh if (self.o.resizeRefresh) { self.resizeRefresh(); } // Click Event self.$paginationItem.on('click', function(e){ self.moveBind(self.$paginationItem.index(this) * self.group); e.preventDefault(); }); self.$prevNavi.on('click', function(e){ self.moveBind(self.index - self.group, this); if (self.isLastOnScreen) { self.isLastOnScreen = false; self.$nextNavi.removeClass(self.o.disableClass); } e.preventDefault(); }); self.$nextNavi.on('click', function(e){ self.moveBind(self.index + self.group, this); e.preventDefault(); }); if (self.touch) self.touchSlide(); self.$list.data('lqslider', true); self.on_init(self.$element, self); }; fn.touchSlide = function() { var self = this, moveNext = true, movePrev = true var eventStart = 'mousedown', eventEnd = 'mouseup', eventMove = 'mousemove'; if (/Android|webOS|iPhone|iPod|iPad|BlackBerry/i.test(navigator.userAgent)) { eventStart = 'touchstart'; eventEnd = 'touchend'; eventMove = 'touchmove'; } self.$list.on(eventStart, function(e) { self.diff = 0; self.pause(); if (self.o.vertical) { var startY = e.pageY || e.originalEvent.touches[0].pageY; self.$element.on(eventMove, function(e) { var moveY = e.pageY || e.originalEvent.touches[0].pageY; self.diff = (startY - moveY) / self.elementSize * 70; }) } else { var startX = e.pageX || e.originalEvent.touches[0].pageX; self.$element.on(eventMove, function(e) { var moveX = e.pageX || e.originalEvent.touches[0].pageX; self.diff = (startX - moveX) / self.elementSize * 70; // if (self.diff < -8 || self.diff > 8) // self.$list.css({'transform':'translateX('+(-(self.diff*2))+'px)'}) }) } }) self.$list.on(eventEnd, function(e) { self.$element.off(eventMove); if (self.o.autoPlay) { self.autoPlay(); } if (self.diff > -8 && self.diff < 8 && self.diff != 0) { self.play(); return; } if (self.o.direction == 'rtl') { if (self.diff <= -8 && moveNext) { self.moveBind(self.index + self.group); return; } if (self.diff >= 8 && movePrev) { self.moveBind(self.index - self.group); return; } } else { if (self.diff <= -8 && movePrev) { self.moveBind(self.index - self.group); return; } if (self.diff >= 8 && moveNext) { self.moveBind(self.index + self.group); return; } } // self.$list.css({'transform':'translateX(0px)'}) }) self.$element.on('lqslide:moveend',function() { if (!self.loop) { movePrev = !(self.index - (self.group - 1) <= 0) moveNext = !(self.index + (self.group - 1) >= self.$item.length -1) } }) // self.$list.css('touch-action','none'); } fn.itemMarginCalc = function() { var self = this; // self.itemMargin = (self.o.vertical) ? (parseInt(self.$item.css('marginTop')) + parseInt(self.$item.css('marginBottom'))) : (parseInt(self.$item.css('marginLeft')) + parseInt(self.$item.css('marginRight'))); return (self.o.vertical) ? (parseInt(self.$item.css('marginTop')) + parseInt(self.$item.css('marginBottom'))) : (parseInt(self.$item.css('marginLeft')) + parseInt(self.$item.css('marginRight'))); } fn.inViewport = function(item,dir) { // MODE : start - full - half var self = this; // var _window = $(window); var docViewLeft = self.$viewportWrapper.offset().left; var docViewRight = docViewLeft + self.$viewportWrapper.width(); switch(self.o.viewportMode) { default : case 'start' : var elemLeft = item.offset().left; break; case 'full' : var elemLeft = item.offset().left + item.width(); break; case 'half' : var elemLeft = item.offset().left + (item.width() / 2); break; } var elemRight = item.offset().left + item.width(); return ((elemRight <= docViewRight) && (elemLeft >= docViewLeft)); } fn.indexUpdate = function (index, moved) { var self = this; var indexTo = index; if (!self.isMoving) { //loop & move if (self.loop && moved !== 'moved') { if (index < - self.group) { indexTo = self.$item.length - 1; } if (index > (self.$item.length - 1) + self.group) { indexTo = 0; } //loop & move } else if (self.loop && moved === 'moved') { if (index < 0) { indexTo = self.$item.length + index; } if (index > self.$item.length - 1) { indexTo = index - self.$item.length; } //Loop } else { if (self.group > 1) { if (index < 0) { indexTo = (Math.ceil( (self.$item.length) / self.group ) - 1) * self.group; } } else { if (index < 0) { indexTo = self.$item.length - 1; } } if (index > self.$item.length - 1){ indexTo = 0; } } //self.index = indexTo; if (self.index === indexTo) { return false; } else { self.index = indexTo; return true; } } else { return false; } }; fn.makeClone = function () { var self = this; var i; var j; var matchItem = Math.ceil(self.elementSize / self.itemSize); self.clonePrependNum = self.cloneAppendNum = (matchItem == Infinity) ? 0 : matchItem; self.$list.find($('.' + self.o.cloneClass)).remove(); //prepend for (i = 0, j = self.$item.length - 1; i < self.clonePrependNum; i++) { self.$list.prepend( self.$item.clone().addClass(self.o.cloneClass).removeClass(self.o.currentClass)[j] ); (j <= 0)? j = self.$item.length - 1 : j--; } //append for (i = 0, j = 0; i < self.cloneAppendNum; i++) { self.$list.append( self.$item.clone().addClass(self.o.cloneClass).removeClass(self.o.currentClass)[j] ); (j >= self.$item.length - 1)? j = 0 : j++; } }; fn.setListStyle = function () { var self = this; var prop = {}; prop[self.sizeProp] = self.calcListSize() + 'px';//height, width if (!self.o.listHeightType){ prop[self.marginProp] = self.calcListMargin() + 'px';//marginTop, marginRight } self.$list.css(prop); }; fn.calcListSize = function () { var self = this; if (self.o.listHeightType === 'max') { //return max $item height } else if (self.o.listHeightType === 'auto') { //return auto $litem[index] height. } else { return (self.$item.length + self.clonePrependNum + self.cloneAppendNum ) * self.itemSize ; } }; fn.calcItemSize = function() { var self = this, itemSize = 0; if (!self.o.fixedToParent) { itemSize = (self.o.vertical) ? self.$item.outerHeight(true) : self.$item.outerWidth(true); } else { itemSize = (self.o.vertical) ? self.$element.height() : self.$element.width(); } return itemSize; } fn.calcListMargin = function () { var self = this; return - ( (self.itemSize * (self.index + self.clonePrependNum)) - self.calcPos_x() ); }; fn.calcResponsiveItemSize = function () { var self = this; if ($.isEmptyObject(self.tempConfig['element']) && self.responsiveWrapSelector) { self.tempConfig['element'] = self.$element } if (self.tempConfigSet) { self.$element = self.tempConfig['element'] } if(self.responsiveWrapSelector) { self.$element = self.$element.find(self.responsiveWrapSelector); } self.elementSize = (self.o.vertical) ? self.$element.outerHeight(true) : self.$element.outerWidth(true); var itemSize = (Math.ceil(self.elementSize / parseInt(self.responsiveItemSize)) - self.itemMargin) + self.itemSizeFixNum; if (itemSize == Infinity) self.$item.css({width: ''}); else { self.$item.css({width: itemSize}); self.itemSize = (self.o.vertical) ? self.$item.outerHeight(true) : self.$item.outerWidth(true); } }; fn.calcPos_x = function () { var self = this; //number if (!isNaN(self.o.pos_x)) { return self.o.pos_x + self.o.pos_x_fix; //function } else if ($.isFunction(self.o.pos_x)) { return self.o.pos_x() + self.o.pos_x_fix; } else { switch (self.o.pos_x){ case 'left': return 0 + self.o.pos_x_fix; break; case 'center': return (self.elementSize / 2) - (self.itemSize / 2) + self.o.pos_x_fix; break; case 'right': return (self.elementSize - self.itemSize) + self.o.pos_x_fix; break; default: return 0; break; } } }; fn.moveBind = function (index, element) { var self = this; //click class 'disable' if ($(element).hasClass(self.o.disableClass)) { return false;} //index if(!self.indexUpdate(index)) { return false; } //current self.addCurrentClass(); if (self.o.currentHighlight) { self.highlightEffect(); } //loopingDisabled if (self.loopingDisabled) { self.loopingDisabledFn(); } self.animate(); }; fn.animate = function () { var self = this; switch (self.o.animate) { case 'slide': self.animateSlide(); break; case 'fade': self.animateFade(); break; default: self.animateSlide(); break; } }; fn.animateSlide = function () { var self = this; var prop = {}; prop[self.marginProp] = self.calcListMargin() + 'px';//marginTop, marginRight // prop['Transform'] = 'translateX(0)'; if (!self.isMoving) { self.isMoving = true; self.$element.trigger('lqslide:movestart'); self.on_start(self.$element, self); // self.$list.css({'transform':'translateX(0)'}, self.o.speed); self.$list.animate( prop,{ duration: self.o.speed, easing: self.o.easing, complete: function(){ self.isMoving = false; if (self.loop) { //index self.indexUpdate(self.index, 'moved'); self.on_moved(self.$list.children().eq(self.clonePrependNum + self.index), self); self.setListStyle(); } self.addCurrentClass(); if (self.o.currentHighlight) { self.highlightEffect(); } self.$element.trigger('lqslide:moveend'); self.on_end(self.$element, self); //self.$list.find('img').each(function() { // if ($(this).hasClass('lazyload') && !$(this).hasClass('lazy-loaded')) { // $(this).lazyLoadXT(); // } //}) if(self.inViewport(self.$list.children().eq(self.$item.length - 1))) { self.on_last(self.$list.children().eq(self.$item.length - 1), self, self.index); } if(self.index == self.$item.length - 1) { self.on_last_item(self.$list.children().eq(self.$item.length - 1), self, self.index); } if (self.stopOnlast && !self.loop) { if (self.inViewport(self.$list.children().eq(self.$item.length - 1))) { self.isLastOnScreen = true; self.$nextNavi.addClass(self.o.disableClass) } } }, queue: false }) } }; fn.animateFade = function () { var self = this; if (!self.isMoving) { self.$element.trigger('lqslide:movestart'); self.on_start(self.$element, self); self.isMoving = true; self.$item.css({ zIndex: self.o.fadeZIndexBase }); self.$item.eq(self.index) .css({ zIndex: self.o.fadeZIndexBase + 1 }) .fadeIn(self.o.speed, function () { self.$item.not(self.$item.eq(self.index)).fadeOut(); self.setListStyle(); self.isMoving = false; self.$element.trigger('lqslide:moveend'); self.on_end(self.$element, self); }); } }; fn.addCurrentClass = function () { var self = this; var paginationIndex; //currentClass self.$allList.children().removeClass(self.o.currentClass); //$item current self.$list.children().eq(self.clonePrependNum + self.index).addClass(self.o.currentClass); //$item $paginationItem current if (self.index > self.$item.length -1) { paginationIndex = 0; //$item $paginationItem current } else if (self.index < 0) { paginationIndex = Math.floor( (self.$item.length + self.index) / self.group ); } else { paginationIndex = Math.floor(self.index / self.group); } self.$paginationItem.eq(paginationIndex).addClass(self.o.currentClass); }; fn.highlightEffect = function () { var self = this; self.$paginationItem.animate({opacity: 0.4}, {duration: 300, queue: false}); self.$paginationItem + $('.' + self.o.currentClass).animate({opacity: 1}, {duration: 300, queue: false}); } fn.autoPlay = function () { var self = this, autoPlayInterval; autoPlayInterval = (self.o.autoPlayInterval >= 40) ? self.o.autoPlayInterval : 40; self.autoPlayInstance = function(){ if (self.o.autoPlayStopLastItem && self.index >= self.$item.length - self.group) { clearInterval(self.timer); } else { self.moveBind(self.index + 1); } }; setTimeout(function () { self.timer = setInterval(self.autoPlayInstance, autoPlayInterval); }, self.o.autoPlayStartDelay); if (self.o.autoPlayHoverStop) { self.setHoverAction(); } }; fn.loopingDisabledFn = function () { var self = this; if (self.index - (self.group - 1) <= 0){ self.$prevNavi.addClass(self.o.disableClass) } else { self.$prevNavi.removeClass(self.o.disableClass) } if (self.index + (self.group - 1) >= self.$item.length -1){ self.$nextNavi.addClass(self.o.disableClass) } else { self.$nextNavi.removeClass(self.o.disableClass) } }; fn.resizeRefresh = function () { var self = this; var windowsize = (self.o.vertical) ? $(window).height() : $(window).width(); $(window).on('resize', function (e) { var objectsize = (self.o.vertical) ? $(this).height() : $(this).width(); if (objectsize != windowsize) { windowsize = objectsize; if (self.o.resizeTimer) { var _INTERVAL = self.o.resizeTimer; if (self._timer) { clearTimeout(self._timer); self._timer = null; } self._timer = setTimeout(function () { self.reset(); if (self.o.responsive){ self.break(); } if (self.loop) { self.makeClone(); } if (self.loopingDisabled) { self.loopingDisabledFn(); } self.setListStyle(); self._timer = null; self.on_resize(self.$element, self); }, _INTERVAL); } else { self.reset(); if (self.o.responsive){ self.break(); } if (self.loop) { self.makeClone(); } self.setListStyle(); self.on_resize(self.$element, self); } } }); }; fn.refreshSlider = function () { var self = this; if (self.o.responsive){ self.break(); } if (self.loop) { self.makeClone(); } // self.$element = $element; self.$list = self.$element.find($(self.o.listSelector)); self.$item = self.$list.find($(self.o.itemSelector)); self.setListStyle(); if (self.o.autoPlay) { self.autoPlay(); } if (self.loopingDisabled) { self.loopingDisabledFn(); } if (self.touch) self.touchSlide(); }; fn.break = function() { var self = this; self.resposiveObj = []; if (self.o.responsive) { ww = $(window).width(); self.o.responsive.sort(function(a,b) { return a.point < b.point ? 1 : ((b.point < a.point) ? -1 : 0); }) for (var i = 0; i < self.o.responsive.length; i++) { if (typeof self.o.responsive[i] != 'undefined' && ww < self.o.responsive[i].point) { self.breakpoint = self.o.responsive[i].point; self.resposiveObj = self.o.responsive[i]; } } } if (self.resposiveObj.config) { $.each(self.resposiveObj.config, function(i,v) { if (!self.tempConfigSet) self.tempConfig[i] = self[i]; self[i] = v }) self.tempConfigSet = true; } else { if (!$.isEmptyObject(self.tempConfig)) { for (var i in self.tempConfig) { self[i] = self.tempConfig[i] } } } self.reset(); } fn.reset = function() { var self = this; self.itemSize = self.calcItemSize(); self.elementSize = self.$element.outerWidth(true); self.$list.css(self.marginProp, 0); // self.$list.find('.'+self.o.currentClass).removeClass(self.o.currentClass) self.$allList.children().removeClass(self.o.currentClass); self.clonePrependNum = 0; self.index = self.o.start; self.isLastOnScreen = false; if (self.o.fixedToParent) { self.$item.css('width' ,self.itemSize); } if (!self.loop) { self.$list.find(self.o.cloneClass).remove(); } // self.$list.css('touch-action',''); setTimeout(function() { self.moveBind(self.o.start); self.addCurrentClass(); },1) } })(LqSlide.prototype); /** * $.fn.liquidLqSlide */ $.fn.lqslider = function (options) { return this.each(function () { var $this = $(this); $this.data('lqslide', new LqSlide($this, options)); }); }; })(jQuery, this);