/* * File: jquery.flexisel1.js * Version: 1.0.2 * Description: Responsive carousel jQuery plugin * Author: 9bit Studios * Copyright 2012, 9bit Studios * http://www.9bitstudios.com * Free to use and abuse under the MIT license. * http://www.opensource.org/licenses/mit-license.php */ (function ($) { $.fn.flexisel = function(options) { var defaults = $.extend({ visibleItems : 5, animationSpeed : 200, autoPlay : false, autoPlaySpeed : 3000, pauseOnHover : true, setMaxWidthAndHeight : false, enableResponsiveBreakpoints : true, flipPage: false, clone : true, responsiveBreakpoints : { portrait: { changePoint:480, visibleItems: 1 }, landscape: { changePoint:640, visibleItems: 2 }, tablet: { changePoint:768, visibleItems: 3 } } }, options); /****************************** Private Variables *******************************/ var object = $(this); var settings = $.extend(defaults, options); var itemsWidth; // Declare the global width of each item in carousel var canNavigate = true; var itemsVisible = settings.visibleItems; // Get visible items var totalItems = object.children().length; // Get number of elements var responsivePoints = []; /****************************** Public Methods *******************************/ var methods = { init : function() { return this.each(function() { methods.appendHTML(); methods.setEventHandlers(); methods.initializeItems(); }); }, /****************************** Initialize Items Fully initialize everything. Plugin is loaded and ready after finishing execution *******************************/ initializeItems : function() { var listParent = object.parent(); var innerHeight = listParent.height(); var childSet = object.children(); methods.sortResponsiveObject(settings.responsiveBreakpoints); var innerWidth = listParent.width(); // Set widths itemsWidth = (innerWidth) / itemsVisible; childSet.width(itemsWidth); if (settings.clone) { childSet.last().insertBefore(childSet.first()); childSet.last().insertBefore(childSet.first()); object.css({ 'left' : -itemsWidth }); } object.fadeIn(); $(window).trigger("resize"); // needed to position arrows correctly }, /****************************** Append HTML Add additional markup needed by plugin to the DOM *******************************/ appendHTML : function() { object.addClass("nbs-flexisel-ul"); object.wrap("
"); object.find("li").addClass("nbs-flexisel-item"); var flexiselInner = object.parent(); // flexisel-inner if (settings.setMaxWidthAndHeight) { var baseWidth = $(".nbs-flexisel-item img").width(); var baseHeight = $(".nbs-flexisel-item img").height(); $(".nbs-flexisel-item img").css("max-width", baseWidth); $(".nbs-flexisel-item img").css("max-height", baseHeight); } $("
").insertAfter(flexiselInner); if (settings.clone) { var cloneContent = object.children().clone(); object.append(cloneContent); } }, /****************************** Set Event Handlers Set events: click, resize, etc *******************************/ setEventHandlers : function() { var listParent = object.parent(); var flexiselInner = listParent.parent(); var childSet = object.children(); var leftArrow = flexiselInner.find(".nbs-flexisel-nav-left"); var rightArrow = flexiselInner.find(".nbs-flexisel-nav-right"); $(window).on("resize", function(event) { methods.setResponsiveEvents(); var innerWidth = $(listParent).width(); var innerHeight = $(listParent).height(); itemsWidth = (innerWidth) / itemsVisible; childSet.width(itemsWidth); if (settings.clone) { object.css({ 'left' : -itemsWidth }); }else { object.css({ 'left' : 0 }); } // Hide the arrows if the elements are the same of the visible if (!settings.clone && totalItems <= itemsVisible) { leftArrow.add(rightArrow).css('visibility', 'hidden'); } else { leftArrow.add(rightArrow).css('visibility', 'visible'); var halfArrowHeight = (leftArrow.height()) / 2; var arrowMargin = (innerHeight / 2) - halfArrowHeight; leftArrow.css("top", arrowMargin + "px"); rightArrow.css("top", arrowMargin + "px"); } }); $(leftArrow).on("click", function(event) { methods.scrollLeft(); }); $(rightArrow).on("click", function(event) { methods.scrollRight(); }); if (settings.pauseOnHover === true) { $(".nbs-flexisel-item").on({ mouseenter : function() { canNavigate = false; }, mouseleave : function() { canNavigate = true; } }); } if (settings.autoPlay === true) { setInterval(function() { if (canNavigate === true) methods.scrollRight(); }, settings.autoPlaySpeed); } object[0].addEventListener('touchstart', methods.touchHandler.handleTouchStart, false); object[0].addEventListener('touchmove', methods.touchHandler.handleTouchMove, false); }, /****************************** Set Responsive Events Set breakpoints depending on responsiveBreakpoints *******************************/ setResponsiveEvents: function() { var contentWidth = $('html').width(); if(settings.enableResponsiveBreakpoints) { var largestCustom = responsivePoints[responsivePoints.length-1].changePoint; // sorted array for(var i in responsivePoints) { if(contentWidth >= largestCustom) { // set to default if width greater than largest custom responsiveBreakpoint itemsVisible = settings.visibleItems; break; } else { // determine custom responsiveBreakpoint to use if(contentWidth < responsivePoints[i].changePoint) { itemsVisible = responsivePoints[i].visibleItems; break; } else continue; } } } }, /****************************** Sort Responsive Object Gets all the settings in resposiveBreakpoints and sorts them into an array *******************************/ sortResponsiveObject: function(obj) { var responsiveObjects = []; for(var i in obj) { responsiveObjects.push(obj[i]); } responsiveObjects.sort(function(a, b) { return a.changePoint - b.changePoint; }); responsivePoints = responsiveObjects; }, /****************************** Scroll Left *******************************/ scrollLeft : function() { if (object.position().left < 0) { if (canNavigate === true) { canNavigate = false; var listParent = object.parent(); var innerWidth = listParent.width(); itemsWidth = (innerWidth) / itemsVisible; var childSet = object.children(); var increment = (settings.flipPage)? innerWidth: itemsWidth; object.animate({ 'left' : "+=" + increment }, { queue : false, duration : settings.animationSpeed, easing : "linear", complete : function() { if (settings.clone) { childSet.last().insertBefore(childSet.first()); // Get the first list item and put it after the last list item (that's how the infinite effects is made) } methods.adjustScroll(); canNavigate = true; } }); } } }, /****************************** Scroll Right *******************************/ scrollRight : function() { var listParent = object.parent(); var innerWidth = listParent.width(); itemsWidth = (innerWidth) / itemsVisible; var difObject = (itemsWidth - innerWidth); var objPosition = (object.position().left + ((totalItems-itemsVisible)*itemsWidth)-innerWidth); var increment = (settings.flipPage)? innerWidth: itemsWidth; if((difObject <= Math.ceil(objPosition)) && (!settings.clone)){ if (canNavigate === true) { canNavigate = false; object.animate({ 'left' : "-=" + increment }, { queue : false, duration : settings.animationSpeed, easing : "linear", complete : function() { methods.adjustScroll(); canNavigate = true; } }); } } else if(settings.clone){ if (canNavigate === true) { canNavigate = false; var childSet = object.children(); object.animate({ 'left' : "-=" + increment }, { queue : false, duration : settings.animationSpeed, easing : "linear", complete : function() { childSet.first().insertAfter(childSet.last()); // Get the first list item and put it after the last list item (that's how the infinite effects is made) methods.adjustScroll(); canNavigate = true; } }); } }; }, /****************************** Adjust Scroll *******************************/ adjustScroll : function() { var listParent = object.parent(); var childSet = object.children(); var innerWidth = listParent.width(); itemsWidth = (innerWidth) / itemsVisible; childSet.width(itemsWidth); var increment = (settings.flipPage)? innerWidth: itemsWidth; if (settings.clone) { object.css({ 'left' : -increment }); } }, touchHandler: { xDown: null, yDown: null, handleTouchStart: function(evt) { this.xDown = evt.touches[0].clientX; this.yDown = evt.touches[0].clientY; }, handleTouchMove: function (evt) { if (!this.xDown || !this.yDown) { return; } var xUp = evt.touches[0].clientX; var yUp = evt.touches[0].clientY; var xDiff = this.xDown - xUp; var yDiff = this.yDown - yUp; // only comparing xDiff // compare which is greater against yDiff to determine whether left/right or up/down e.g. if (Math.abs( xDiff ) > Math.abs( yDiff )) if (Math.abs( xDiff ) > 0) { if ( xDiff > 0 ) { // swipe left methods.scrollRight(); } else { //swipe right methods.scrollLeft(); } } /* reset values */ this.xDown = null; this.yDown = null; canNavigate = true; } } }; if (methods[options]) { // $("#element").pluginName('methodName', 'arg1', 'arg2'); return methods[options].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof options === 'object' || !options) { // $("#element").pluginName({ option: 1, option:2 }); return methods.init.apply(this); } else { $.error('Method "' + method + '" does not exist in flexisel plugin!'); } }; })(jQuery);