1/* 2* File: jquery.flexisel.js 3* Version: 2.2.2 4* Description: Responsive carousel jQuery plugin 5* Author: 9bit Studios 6* Copyright 2016, 9bit Studios 7* http://www.9bitstudios.com 8* Free to use and abuse under the MIT license. 9* http://www.opensource.org/licenses/mit-license.php 10*/ 11 12(function ($) { 13 14 $.fn.flexisel = function (options) { 15 16 var defaults = $.extend({ 17 visibleItems: 4, 18 itemsToScroll: 3, 19 animationSpeed: 400, 20 infinite: true, 21 navigationTargetSelector: null, 22 autoPlay: { 23 enable: false, 24 interval: 5000, 25 pauseOnHover: true 26 }, 27 responsiveBreakpoints: { 28 portrait: { 29 changePoint:480, 30 visibleItems: 1, 31 itemsToScroll: 1 32 }, 33 landscape: { 34 changePoint:640, 35 visibleItems: 2, 36 itemsToScroll: 1 37 }, 38 tablet: { 39 changePoint:768, 40 visibleItems: 1, 41 itemsToScroll: 1 42 } 43 }, 44 loaded: function(){ }, 45 before: function(){ }, 46 after: function(){ }, 47 resize: function(){ } 48 }, options); 49 50 /****************************** 51 Private Variables 52 *******************************/ 53 54 var object = $(this); 55 var settings = $.extend(defaults, options); 56 var itemsWidth; 57 var canNavigate = true; 58 var itemCount; 59 var itemsVisible = settings.visibleItems; 60 var itemsToScroll = settings.itemsToScroll; 61 var responsivePoints = []; 62 var resizeTimeout; 63 var autoPlayInterval; 64 65 /****************************** 66 Public Methods 67 *******************************/ 68 69 var methods = { 70 71 init: function() { 72 return this.each(function () { 73 methods.appendHTML(); 74 methods.setEventHandlers(); 75 methods.initializeItems(); 76 }); 77 }, 78 79 /****************************** 80 Initialize Items 81 *******************************/ 82 83 initializeItems: function() { 84 85 var obj = settings.responsiveBreakpoints; 86 for(var i in obj) { responsivePoints.push(obj[i]); } 87 responsivePoints.sort(function(a, b) { return a.changePoint - b.changePoint; }); 88 var childSet = object.children(); 89 childSet.first().addClass("index"); 90 itemsWidth = methods.getCurrentItemWidth(); 91 itemCount = childSet.length; 92 childSet.width(itemsWidth); 93 if(settings.infinite) { 94 methods.offsetItemsToBeginning(Math.floor(childSet.length / 2)); 95 object.css({ 96 'left': -itemsWidth * Math.floor(childSet.length / 2) 97 }); 98 } 99 $(window).trigger('resize'); 100 object.fadeIn(); 101 settings.loaded.call(this, object); 102 103 }, 104 105 /****************************** 106 Append HTML 107 *******************************/ 108 109 appendHTML: function() { 110 111 object.addClass("nbs-flexisel-ul"); 112 object.wrap("<div class='nbs-flexisel-container'><div class='nbs-flexisel-inner'></div></div>"); 113 object.find("li").addClass("nbs-flexisel-item"); 114 115 if(settings.navigationTargetSelector && $(settings.navigationTargetSelector).length > 0) { 116 $("<div class='nbs-flexisel-nav-left'></div><div class='nbs-flexisel-nav-right'></div>").appendTo(settings.navigationTargetSelector); 117 } else { 118 settings.navigationTargetSelector = object.parent(); 119 $("<div class='nbs-flexisel-nav-left'></div><div class='nbs-flexisel-nav-right'></div>").insertAfter(object); 120 } 121 122 if(settings.infinite) { 123 var childSet = object.children(); 124 var cloneContentBefore = childSet.clone(); 125 var cloneContentAfter = childSet.clone();
126 object.prepend(cloneContentBefore); 127 object.append(cloneContentAfter); 128 } 129 130 }, 131 132 133 /****************************** 134 Set Event Handlers 135 *******************************/ 136 setEventHandlers: function() { 137 var self = this; 138 var childSet = object.children(); 139 140 $(window).on("resize", function(event){ 141 canNavigate = false; 142 clearTimeout(resizeTimeout); 143 resizeTimeout = setTimeout(function(){ 144 canNavigate = true; 145 methods.calculateDisplay(); 146 itemsWidth = methods.getCurrentItemWidth(); 147 childSet.width(itemsWidth); 148 149 if(settings.infinite) { 150 object.css({ 151 'left': -itemsWidth * Math.floor(childSet.length / 2) 152 }); 153 } else { 154 methods.clearDisabled(); 155 $(settings.navigationTargetSelector).find(".nbs-flexisel-nav-left").addClass('disabled'); 156 object.css({ 157 'left': 0 158 }); 159 } 160 161 settings.resize.call(self, object); 162 163 }, 100); 164 165 }); 166 167 $(settings.navigationTargetSelector).find(".nbs-flexisel-nav-left").on("click", function (event) { 168 methods.scroll(true); 169 }); 170 171 $(settings.navigationTargetSelector).find(".nbs-flexisel-nav-right").on("click", function (event) { 172 methods.scroll(false); 173 }); 174 175 if(settings.autoPlay.enable) { 176 177 methods.setAutoplayInterval(); 178 179 if (settings.autoPlay.pauseOnHover === true) { 180 object.on({ 181 mouseenter : function() { 182 canNavigate = false; 183 }, 184 mouseleave : function() { 185 canNavigate = true; 186 } 187 }); 188 } 189 190 } 191 192 object[0].addEventListener('touchstart', methods.touchHandler.handleTouchStart, false); 193 object[0].addEventListener('touchmove', methods.touchHandler.handleTouchMove, false); 194 195 }, 196 197 /****************************** 198 Calculate Display 199 *******************************/ 200 201 calculateDisplay: function() { 202 var contentWidth = $('html').width(); 203 var largestCustom = responsivePoints[responsivePoints.length-1].changePoint; // sorted array 204 205 for(var i in responsivePoints) { 206 207 if(contentWidth >= largestCustom) { // set to default if width greater than largest custom responsiveBreakpoint 208 itemsVisible = settings.visibleItems; 209 itemsToScroll = settings.itemsToScroll; 210 break; 211 } 212 else { // determine custom responsiveBreakpoint to use 213 214 if(contentWidth < responsivePoints[i].changePoint) { 215 itemsVisible = responsivePoints[i].visibleItems; 216 itemsToScroll = responsivePoints[i].itemsToScroll; 217 break; 218 } 219 else { 220 continue; 221 } 222 } 223 } 224 225 }, 226 227 /****************************** 228 Scroll 229 *******************************/ 230 231 scroll: function(reverse) { 232 233 if(typeof reverse === 'undefined') { reverse = true } 234 235 if(canNavigate == true) { 236 canNavigate = false;
237 settings.before.call(this, object); 238 itemsWidth = methods.getCurrentItemWidth(); 239 240 if(settings.autoPlay.enable) { 241 clearInterval(autoPlayInterval); 242 } 243 244 if(!settings.infinite) { 245 246 var scrollDistance = itemsWidth * itemsToScroll; 247 248 if(reverse) { 249 object.animate({ 250 'left': methods.calculateNonInfiniteLeftScroll(scrollDistance) 251 }, settings.animationSpeed, function(){ 252 settings.after.call(this, object); 253 canNavigate = true; 254 }); 255 256 } else { 257 object.animate({ 258 'left': methods.calculateNonInfiniteRightScroll(scrollDistance) 259 },settings.animationSpeed, function(){ 260 settings.after.call(this, object); 261 canNavigate = true; 262 }); 263 } 264 265 266 267 } else { 268 object.animate({ 269 'left' : reverse ? "+=" + itemsWidth * itemsToScroll : "-=" + itemsWidth * itemsToScroll 270 }, settings.animationSpeed, function() { 271 settings.after.call(this, object); 272 canNavigate = true; 273 274 if(reverse) { 275 methods.offsetItemsToBeginning(itemsToScroll); 276 } else { 277 methods.offsetItemsToEnd(itemsToScroll); 278 } 279 methods.offsetSliderPosition(reverse); 280 281 }); 282 } 283 284 if(settings.autoPlay.enable) { 285 methods.setAutoplayInterval(); 286 } 287 288 } 289 }, 290 291 touchHandler: { 292 293 xDown: null, 294 yDown: null, 295 handleTouchStart: function(evt) { 296 this.xDown = evt.touches[0].clientX; 297 this.yDown = evt.touches[0].clientY; 298 }, 299 handleTouchMove: function (evt) { 300 if (!this.xDown || !this.yDown) { 301 return; 302 } 303 304 var xUp = evt.touches[0].clientX; 305 var yUp = evt.touches[0].clientY; 306 307 var xDiff = this.xDown - xUp; 308 var yDiff = this.yDown - yUp; 309 310 // only comparing xDiff 311 // compare which is greater against yDiff to determine whether left/right or up/down e.g. if (Math.abs( xDiff ) > Math.abs( yDiff )) 312 if (Math.abs( xDiff ) > 0) { 313 if ( xDiff > 0 ) { 314 // swipe left 315 methods.scroll(false); 316 } else { 317 //swipe right 318 methods.scroll(true); 319 } 320 } 321 322 /* reset values */ 323 this.xDown = null; 324 this.yDown = null; 325 canNavigate = true; 326 } 327 }, 328 329 /****************************** 330 Utility Functions 331 *******************************/ 332 333 getCurrentItemWidth: function() { 334 return (object.parent().width())/itemsVisible; 335 }, 336 337 offsetItemsToBeginning: function(number) { 338 if(typeof number === 'undefined') { number = 1 } 339 for(var i = 0; i < number; i++) {
340 object.children().last().insertBefore(object.children().first()); 341 } 342 }, 343 344 offsetItemsToEnd: function(number) { 345 if(typeof number === 'undefined') { number = 1 } 346 for(var i = 0; i < number; i++) { 347 object.children().first().insertAfter(object.children().last()); 348 } 349 }, 350 351 offsetSliderPosition: function(reverse) { 352 var left = parseInt(object.css('left').replace('px', '')); 353 if (reverse) { 354 left = left - itemsWidth * itemsToScroll; 355 } else { 356 left = left + itemsWidth * itemsToScroll; 357 } 358 object.css({ 359 'left': left 360 }); 361 }, 362 363 getOffsetPosition: function() { 364 return parseInt(object.css('left').replace('px', '')); 365 }, 366 367 calculateNonInfiniteLeftScroll: function(toScroll) { 368 369 methods.clearDisabled(); 370 if(methods.getOffsetPosition() + toScroll >= 0) { 371 $(settings.navigationTargetSelector).find(".nbs-flexisel-nav-left").addClass('disabled'); 372 return 0; 373 } else { 374 return methods.getOffsetPosition() + toScroll; 375 } 376 }, 377 378 calculateNonInfiniteRightScroll: function(toScroll){ 379 380 methods.clearDisabled(); 381 var negativeOffsetLimit = (itemCount * itemsWidth) - (itemsVisible * itemsWidth); 382 383 if(methods.getOffsetPosition() - toScroll <= -negativeOffsetLimit) { 384 $(settings.navigationTargetSelector).find(".nbs-flexisel-nav-right").addClass('disabled'); 385 return -negativeOffsetLimit; 386 } else { 387 return methods.getOffsetPosition() - toScroll; 388 } 389 }, 390 391 setAutoplayInterval: function(){ 392 autoPlayInterval = setInterval(function() { 393 if (canNavigate) { 394 methods.scroll(false); 395 } 396 }, settings.autoPlay.interval); 397 }, 398 399 clearDisabled: function() { 400 var parent = $(settings.navigationTargetSelector); 401 parent.find(".nbs-flexisel-nav-left").removeClass('disabled'); 402 parent.find(".nbs-flexisel-nav-right").removeClass('disabled'); 403 } 404 405 }; 406 407 if (methods[options]) { // $("#element").pluginName('methodName', 'arg1', 'arg2'); 408 return methods[options].apply(this, Array.prototype.slice.call(arguments, 1)); 409 } else if (typeof options === 'object' || !options) { // $("#element").pluginName({ option: 1, option:2 }); 410 return methods.init.apply(this); 411 } else { 412 $.error( 'Method "' + method + '" does not exist in flexisel plugin!'); 413 } 414}; 415 416})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.