1/** 2 * BxSlider v4.1.2 - Fully loaded, responsive content slider 3 * http://bxslider.com 4 * 5 * Copyright 2014, Steven Wanderski - http://stevenwanderski.com - http://bxcreative.com 6 * Written while drinking Belgian ales and listening to jazz 7 * 8 * Released under the MIT license - http://opensource.org/licenses/MIT 9 */ 10 11;(function($){ 12 13 var plugin = {}; 14 15 var defaults = { 16 17 // GENERAL 18 mode: 'horizontal', 19 slideSelector: '', 20 infiniteLoop: true, 21 hideControlOnEnd: false, 22 speed: 1000, 23 easing: 'linear', 24 slideMargin: 0, 25 startSlide: 0, 26 randomStart: false, 27 captions: false, 28 ticker: false, 29 tickerHover: false, 30 adaptiveHeight: false, 31 adaptiveHeightSpeed: 500, 32 video: false, 33 useCSS: false, 34 preloadImages: 'visible', 35 responsive: true, 36 slideZIndex: 50, 37 wrapperClass: 'bx-wrapper', 38 39 // TOUCH 40 touchEnabled: true, 41 swipeThreshold: 50, 42 oneToOneTouch: true, 43 preventDefaultSwipeX: true, 44 preventDefaultSwipeY: false, 45 46 // PAGER 47 pager: false, 48 pagerType: 'full', 49 pagerShortSeparator: ' / ', 50 pagerSelector: null, 51 buildPager: null, 52 pagerCustom: null, 53 54 // CONTROLS 55 controls: true, 56 nextText: 'Next', 57 prevText: 'Prev', 58 nextSelector: null, 59 prevSelector: null, 60 autoControls: false, 61 startText: 'Start', 62 stopText: 'Stop', 63 autoControlsCombine: false, 64 autoControlsSelector: null, 65 66 // AUTO 67 auto: true, 68 pause: 4000, 69 autoStart: true, 70 autoDirection: 'next', 71 autoHover: true, 72 autoDelay: 0, 73 autoSlideForOnePage: false, 74 75 // CAROUSEL 76 minSlides: 1, 77 maxSlides: 1, 78 moveSlides: 0, 79 slideWidth: 0, 80 widthType: 'px', 81 82 // CALLBACKS 83 onSliderLoad: function() {}, 84 onSlideBefore: function() {}, 85 onSlideAfter: function() {}, 86 onSlideNext: function() {}, 87 onSlidePrev: function() {}, 88 onSliderResize: function() {} 89 }; 90 91 $.fn.bxSlider = function(options){ 92 93 if(this.length == 0) return this; 94 95 // support mutltiple elements 96 if(this.length > 1){ 97 this.each(function(){$(this).bxSlider(options)}); 98 return this; 99 } 100 101 // create a namespace to be used throughout the plugin 102 var slider = {}; 103 // set a reference to our slider element 104 var el = this; 105 plugin.el = this; 106 107 /** 108 * Makes slideshow responsive 109 */ 110 // first get the original window dimens (thanks alot IE) 111 var windowWidth = $(window).width(); 112 var windowHeight = $(window).height(); 113 114 115 116 /** 117 * =================================================================================== 118 * = PRIVATE FUNCTIONS 119 * =================================================================================== 120 */ 121 122 /** 123 * Initializes namespace settings to be used throughout plugin 124 */ 125 var init = function(){ 126 // merge user-supplied options with the defaults 127 slider.settings = $.extend({}, defaults, options); 128 // parse slideWidth setting 129 slider.settings.slideWidth = parseInt(slider.settings.slideWidth); 130 slider.settings.pagerType = parseInt(slider.settings.navigation); 131 slider.settings.slideMargin = parseInt(slider.settings.slideMargin); 132 slider.settings.oneToOneTouch = slider.settings.oneToOne; 133 // store the original children 134 slider.children = el.children(slider.settings.slideSelector); 135 // check if actual number of slides is less than minSlides / maxSlides 136 if(slider.children.length < slider.settings.minSlides) slider.settings.minSlides = slider.children.length; 137 if(slider.children.length < slider.settings.maxSlides) slider.settings.maxSlides = slider.children.length; 138 // if random start, set the startSlide setting to random number 139 if(slider.settings.randomStart) slider.settings.startSlide = Math.floor(Math.random() * slider.children.length); 140 // store active slide information 141 slider.active = { index: slider.settings.startSlide }; 142 // store if the slider is in carousel mode (displaying / moving multiple slides) 143 slider.carousel = slider.settings.minSlides > 1 || slider.settings.maxSlides > 1; 144 // if carousel, force preloadImages = 'all' 145 if(slider.carousel) slider.settings.preloadImages = 'all'; 146 // calculate the min / max width thresholds based on min / max number of slides 147 // used to setup and update carousel slides dimensions 148 slider.minThreshold = (slider.settings.minSlides * slider.settings.slideWidth) + ((slider.settings.minSlides - 1) * slider.settings.slideMargin); 149 slider.maxThreshold = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin); 150 // store the current state of the slider (if currently animating, working is true) 151 slider.working = false; 152 // initialize the controls object 153 slider.controls = {}; 154 // initialize an auto interval 155 slider.interval = null; 156 // determine which property to use for transitions 157 slider.animProp = slider.settings.mode == 'vertical' ? 'top' : 'left'; 158 slider.settings.auto = slider.settings.auto == 'enable'; 159 slider.settings.slideshowControls = slider.settings.slideshowControls == 'enable'; 160 slider.settings.pager = slider.settings.pagerEnabled; 161 // determine if hardware acceleration can be used 162 slider.usingCSS = slider.settings.useCSS && slider.settings.mode != 'fade' && (function(){ 163 // create our test div element 164 var div = document.createElement('div'); 165 // css transition properties 166 var props = ['WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective']; 167 // test for each property 168 for(var i in props){ 169 if(div.style[props[i]] !== undefined){ 170 slider.cssPrefix = props[i].replace('Perspective', '').toLowerCase(); 171 slider.animProp = '-' + slider.cssPrefix + '-transform'; 172 return true; 173 } 174 } 175 return false; 176 }()); 177 // if vertical mode always make maxSlides and minSlides equal 178 if(slider.settings.mode == 'vertical') slider.settings.maxSlides = slider.settings.minSlides; 179 // save original style data 180 el.data("origStyle", el.attr("style"));
181 el.children(slider.settings.slideSelector).each(function() { 182 $(this).data("origStyle", $(this).attr("style")); 183 }); 184 185 // perform all DOM / CSS modifications 186 setup(); 187 }; 188 189 /** 190 * Performs all DOM and CSS modifications 191 */ 192 var setup = function(){ 193 // wrap el in a wrapper 194 el.wrap('<div class="' + slider.settings.wrapperClass + '"><div class="bx-viewport"></div></div>'); 195 // store a namspace reference to .bx-viewport 196 slider.viewport = el.parent(); 197 // add a loading div to display while images are loading 198 slider.loader = $('<div class="bx-loading" />'); 199 slider.viewport.prepend(slider.loader); 200 // set el to a massive width, to hold any needed slides 201 // also strip any margin and padding from el 202 el.css({ 203 width: slider.settings.mode == 'horizontal' ? (slider.children.length * 100 + 215) + '%' : 'auto', 204 position: 'relative' 205 }); 206 // if using CSS, add the easing property 207 if(slider.usingCSS && slider.settings.easing){ 208 el.css('-' + slider.cssPrefix + '-transition-timing-function', slider.settings.easing); 209 // if not using CSS and no easing value was supplied, use the default JS animation easing (swing) 210 }else if(!slider.settings.easing){ 211 slider.settings.easing = 'swing'; 212 } 213 var slidesShowing = getNumberSlidesShowing(); 214 // make modifications to the viewport (.bx-viewport) 215 slider.viewport.css({ 216 width: '100%', 217 overflow: 'hidden', 218 position: 'relative' 219 }); 220 slider.viewport.parent().css({ 221 maxWidth: getViewportMaxWidth() 222 }); 223 // make modification to the wrapper (.bx-wrapper) 224 if(!slider.settings.pager) { 225 slider.viewport.parent().css({ 226 margin: '0 auto 0px' 227 }); 228 } 229 // apply css to all slider children 230 slider.children.css({ 231 'float': slider.settings.mode == 'horizontal' ? 'left' : 'none', 232 listStyle: 'none', 233 position: 'relative' 234 }); 235 // apply the calculated width after the float is applied to prevent scrollbar interference 236 slider.children.css('width', getSlideWidth()); 237 // if slideMargin is supplied, add the css 238 if(slider.settings.mode == 'horizontal' && slider.settings.slideMargin > 0) slider.children.css('marginRight', slider.settings.slideMargin); 239 if(slider.settings.mode == 'vertical' && slider.settings.slideMargin > 0) slider.children.css('marginBottom', slider.settings.slideMargin); 240 // if "fade" mode, add positioning and z-index CSS 241 if(slider.settings.mode == 'fade'){ 242 slider.children.css({ 243 position: 'absolute', 244 zIndex: 0, 245 display: 'none' 246 }); 247 // prepare the z-index on the showing element 248 slider.children.eq(slider.settings.startSlide).css({zIndex: slider.settings.slideZIndex, display: 'block'}); 249 } 250 //set thumbnails function 251 /*if(slider.settings.pagerType) { 252 var resources = $('.thumbnails').clone(); 253 slider.settings.buildPager = function(index) { 254 var img = resources.find('li').get(index); 255 var video = $('.supsystic-slider li').get(index); 256 if($(video).children().hasClass('fluid-width-video-wrapper')) { 257 return '<img src="http://placehold.it/' + Math.floor(this.slideWidth/4.0) + 'x' + Math.floor(this.height/3.0) + '&text=Video">'; 258 } 259 return '<img src="' + $(img).find('img').attr('src') + '">'; 260 } 261 } 262 $('.thumbnails').remove();*/ 263 // create an element to contain all slider controls (pager, start / stop, etc) 264 slider.controls.el = $('<div class="bx-controls" />'); 265 // if captions are requested, add them 266 if(slider.settings.captions) appendCaptions(); 267 // check if startSlide is last slide 268 slider.active.last = slider.settings.startSlide == getPagerQty() - 1; 269 // if video is true, set up the fitVids plugin 270 if(slider.settings.video) el.fitVids(); 271 // set the default preload selector (visible) 272 var preloadSelector = slider.children.eq(slider.settings.startSlide); 273 if (slider.settings.preloadImages == "all") preloadSelector = slider.children;
274 // only check for control addition if not in "ticker" mode 275 if(!slider.settings.ticker){ 276 // if pager is requested, add it 277 if(slider.settings.pager) appendPager(); 278 // if controls are requested, add them 279 if(slider.settings.controls) appendControls(); 280 // if auto is true, and auto controls are requested, add them 281 if(slider.settings.auto && slider.settings.autoControls) appendControlsAuto(); 282 //if auto is false, and slideshowControls is true 283 if(!slider.settings.auto && slider.settings.slideshowControls) appendControlsAuto(); 284 //if auto is true and slideshows controls is true 285 if(slider.settings.auto && slider.settings.slideshowControls) appendControlsAuto(); 286 // if any control option is requested, add the controls wrapper 287 if(slider.settings.controls || slider.settings.autoControls || slider.settings.pager) slider.viewport.after(slider.controls.el); 288 // if ticker mode, do not allow a pager 289 }else{ 290 slider.settings.pager = false; 291 } 292 // preload all images, then perform final DOM / CSS modifications that depend on images being loaded 293 loadElements(preloadSelector, start); 294 }; 295 296 var loadElements = function(selector, callback){ 297 var total = selector.find('img, iframe').length; 298 if (total == 0){ 299 callback(); 300 return; 301 } 302 var count = 0; 303 selector.find('img, iframe').each(function(){ 304 $(this).one('load', function() { 305 if(++count == total) callback(); 306 }).each(function() { 307 if(this.complete) $(this).load(); 308 }); 309 }); 310 }; 311 312 /** 313 * Start the slider 314 */ 315 var start = function(){ 316 // if infinite loop, prepare additional slides 317 if(slider.settings.infiniteLoop && slider.settings.mode != 'fade' && !slider.settings.ticker){ 318 var slice = slider.settings.mode == 'vertical' ? slider.settings.minSlides : slider.settings.maxSlides; 319 var sliceAppend = slider.children.slice(0, slice).clone().addClass('bx-clone'); 320 var slicePrepend = slider.children.slice(-slice).clone().addClass('bx-clone'); 321 el.append(sliceAppend).prepend(slicePrepend); 322 } 323 // remove the loading DOM element 324 slider.loader.remove(); 325 // set the left / top position of "el" 326 setSlidePosition(); 327 // if "vertical" mode, always use adaptiveHeight to prevent odd behavior 328 if (slider.settings.mode == 'vertical') slider.settings.adaptiveHeight = true; 329 // set the viewport height 330 slider.viewport.height(getViewportHeight()); 331 // make sure everything is positioned just right (same as a window resize) 332 el.redrawSlider(); 333 // onSliderLoad callback 334 slider.settings.onSliderLoad(slider.active.index); 335 // slider has been fully initialized 336 slider.initialized = true;
337 // bind the resize call to the window 338 if (slider.settings.responsive) $(window).bind('resize', resizeWindow); 339 // if auto is true and has more than 1 page, start the show 340 if (slider.settings.auto && slider.settings.autoStart && (getPagerQty() > 1 || slider.settings.autoSlideForOnePage)) initAuto(); 341 // if ticker is true, start the ticker 342 if (slider.settings.ticker) initTicker(); 343 // if pager is requested, make the appropriate pager link active 344 if (slider.settings.pager) updatePagerActive(slider.settings.startSlide); 345 // check for any updates to the controls (like hideControlOnEnd updates) 346 if (slider.settings.controls) updateDirectionControls(); 347 // if touchEnabled is true, setup the touch events 348 if (slider.settings.touchEnabled && !slider.settings.ticker) initTouch(); 349 }; 350 351 /** 352 * Returns the calculated height of the viewport, used to determine either adaptiveHeight or the maxHeight value 353 */ 354 var getViewportHeight = function(){ 355 var height = 0; 356 // first determine which children (slides) should be used in our height calculation 357 var children = $(); 358 // if mode is not "vertical" and adaptiveHeight is false, include all children 359 if(slider.settings.mode != 'vertical' && !slider.settings.adaptiveHeight){ 360 children = slider.children; 361 }else{ 362 // if not carousel, return the single active child 363 if(!slider.carousel){ 364 children = slider.children.eq(slider.active.index); 365 // if carousel, return a slice of children 366 }else{ 367 // get the individual slide index 368 var currentIndex = slider.settings.moveSlides == 1 ? slider.active.index : slider.active.index * getMoveBy(); 369 // add the current slide to the children 370 children = slider.children.eq(currentIndex); 371 // cycle through the remaining "showing" slides 372 for (i = 1; i <= slider.settings.maxSlides - 1; i++){ 373 // if looped back to the start 374 if(currentIndex + i >= slider.children.length){ 375 children = children.add(slider.children.eq(i - 1)); 376 }else{ 377 children = children.add(slider.children.eq(currentIndex + i)); 378 } 379 } 380 } 381 } 382 // if "vertical" mode, calculate the sum of the heights of the children 383 if(slider.settings.mode == 'vertical'){ 384 children.each(function(index) { 385 height += $(this).outerHeight(); 386 }); 387 // add user-supplied margins 388 if(slider.settings.slideMargin > 0){ 389 height += slider.settings.slideMargin * (slider.settings.minSlides - 1); 390 } 391 // if not "vertical" mode, calculate the max height of the children 392 }else{ 393 height = Math.max.apply(Math, children.map(function(){ 394 return $(this).outerHeight(false); 395 }).get()); 396 } 397 398 if(slider.viewport.css('box-sizing') == 'border-box'){ 399 height += parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom')) + 400 parseFloat(slider.viewport.css('border-top-width')) + parseFloat(slider.viewport.css('border-bottom-width')); 401 }else if(slider.viewport.css('box-sizing') == 'padding-box'){ 402 height += parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom')); 403 } 404 return height; 405 }; 406 407 /** 408 * Returns the calculated width to be used for the outer wrapper / viewport 409 */ 410 var getViewportMaxWidth = function(){ 411 var width = '100%'; 412 413 if(slider.settings.slideWidth > 0){ 414 if(slider.settings.mode == 'horizontal'){ 415 width = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin); 416 }else{ 417 width = slider.settings.slideWidth; 418 } 419 } 420 421 return width; 422 }; 423 424 /** 425 * Returns the calculated width to be applied to each slide 426 */ 427 var getSlideWidth = function(){ 428 // start with any user-supplied slide width 429 var newElWidth = slider.settings.slideWidth; 430 // get the current viewport width 431 var wrapWidth = slider.viewport.width(); 432 // if slide width was not supplied, or is larger than the viewport use the viewport width 433 if(slider.settings.slideWidth == 0 || 434 (slider.settings.slideWidth > wrapWidth && !slider.carousel) || 435 slider.settings.mode == 'vertical'){ 436 newElWidth = wrapWidth; 437 // if carousel, use the thresholds to determine the width 438 }else if(slider.settings.maxSlides > 1 && slider.settings.mode == 'horizontal'){
439 if(wrapWidth > slider.maxThreshold){ 440 // newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.maxSlides - 1))) / slider.settings.maxSlides; 441 }else if(wrapWidth < slider.minThreshold){ 442 newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.minSlides - 1))) / slider.settings.minSlides; 443 } 444 } 445 return newElWidth; 446 }; 447 448 /** 449 * Returns the number of slides currently visible in the viewport (includes partially visible slides) 450 */ 451 var getNumberSlidesShowing = function(){ 452 var slidesShowing = 1; 453 if(slider.settings.mode == 'horizontal' && slider.settings.slideWidth > 0){ 454 // if viewport is smaller than minThreshold, return minSlides 455 if(slider.viewport.width() < slider.minThreshold){ 456 slidesShowing = slider.settings.minSlides; 457 // if viewport is larger than minThreshold, return maxSlides 458 }else if(slider.viewport.width() > slider.maxThreshold){ 459 slidesShowing = slider.settings.maxSlides; 460 // if viewport is between min / max thresholds, divide viewport width by first child width 461 }else{ 462 var childWidth = slider.children.first().width() + slider.settings.slideMargin; 463 slidesShowing = Math.floor((slider.viewport.width() + 464 slider.settings.slideMargin) / childWidth); 465 } 466 // if "vertical" mode, slides showing will always be minSlides 467 }else if(slider.settings.mode == 'vertical'){ 468 slidesShowing = slider.settings.minSlides; 469 } 470 return slidesShowing; 471 }; 472 473 /** 474 * Returns the number of pages (one full viewport of slides is one "page") 475 */ 476 var getPagerQty = function(){ 477 var pagerQty = 0; 478 // if moveSlides is specified by the user 479 if(slider.settings.moveSlides > 0){ 480 if(slider.settings.infiniteLoop){ 481 pagerQty = Math.ceil(slider.children.length / getMoveBy()); 482 }else{ 483 // use a while loop to determine pages 484 var breakPoint = 0; 485 var counter = 0 486 // when breakpoint goes above children length, counter is the number of pages 487 while (breakPoint < slider.children.length){ 488 ++pagerQty; 489 breakPoint = counter + getNumberSlidesShowing(); 490 counter += slider.settings.moveSlides <= getNumberSlidesShowing() ? slider.settings.moveSlides : getNumberSlidesShowing(); 491 } 492 } 493 // if moveSlides is 0 (auto) divide children length by sides showing, then round up 494 }else{ 495 pagerQty = Math.ceil(slider.children.length / getNumberSlidesShowing()); 496 } 497 return pagerQty; 498 }; 499 500 /** 501 * Returns the number of indivual slides by which to shift the slider 502 */ 503 var getMoveBy = function(){ 504 // if moveSlides was set by the user and moveSlides is less than number of slides showing 505 if(slider.settings.moveSlides > 0 && slider.settings.moveSlides <= getNumberSlidesShowing()){ 506 return slider.settings.moveSlides; 507 } 508 // if moveSlides is 0 (auto) 509 return getNumberSlidesShowing(); 510 }; 511 512 /** 513 * Sets the slider's (el) left or top position 514 */ 515 var setSlidePosition = function(){ 516 var position; 517 // if last slide, not infinite loop, and number of children is larger than specified maxSlides 518 if(slider.children.length > slider.settings.maxSlides && slider.active.last && !slider.settings.infiniteLoop){ 519 if (slider.settings.mode == 'horizontal'){ 520 // get the last child's position 521 var lastChild = slider.children.last(); 522 position = lastChild.position(); 523 // set the left position 524 setPositionProperty(-(position.left - (slider.viewport.width() - lastChild.outerWidth())), 'reset', 0); 525 }else if(slider.settings.mode == 'vertical'){ 526 // get the last showing index's position 527 var lastShowingIndex = slider.children.length - slider.settings.minSlides; 528 position = slider.children.eq(lastShowingIndex).position(); 529 // set the top position 530 setPositionProperty(-position.top, 'reset', 0); 531 } 532 // if not last slide 533 }else{ 534 // get the position of the first showing slide 535 position = slider.children.eq(slider.active.index * getMoveBy()).position(); 536 // check for last slide 537 if (slider.active.index == getPagerQty() - 1) slider.active.last = true; 538 // set the repective position 539 if (position != undefined){ 540 if (slider.settings.mode == 'horizontal') setPositionProperty(-position.left, 'reset', 0); 541 else if (slider.settings.mode == 'vertical') setPositionProperty(-position.top, 'reset', 0); 542 } 543 } 544 }; 545 546 /** 547 * Sets the el's animating property position (which in turn will sometimes animate el). 548 * If using CSS, sets the transform property. If not using CSS, sets the top / left property. 549 * 550 * @param value (int) 551 * - the animating property's value 552 * 553 * @param type (string) 'slider', 'reset', 'ticker' 554 * - the type of instance for which the function is being 555 * 556 * @param duration (int) 557 * - the amount of time (in ms) the transition should occupy 558 * 559 * @param params (array) optional 560 * - an optional parameter containing any variables that need to be passed in 561 */ 562 var setPositionProperty = function(value, type, duration, params){ 563 // use CSS transform 564 if(slider.usingCSS){ 565 // determine the translate3d value 566 var propValue = slider.settings.mode == 'vertical' ? 'translate3d(0, ' + value + 'px, 0)' : 'translate3d(' + value + 'px, 0, 0)'; 567 // add the CSS transition-duration 568 el.css('-' + slider.cssPrefix + '-transition-duration', duration / 1000 + 's'); 569 if(type == 'slide'){ 570 // set the property value 571 el.css(slider.animProp, propValue); 572 // bind a callback method - executes when CSS transition completes 573 el.bind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){ 574 // unbind the callback 575 el.unbind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd'); 576 updateAfterSlideTransition(); 577 });
578 }else if(type == 'reset'){ 579 el.css(slider.animProp, propValue); 580 }else if(type == 'ticker'){ 581 // make the transition use 'linear' 582 el.css('-' + slider.cssPrefix + '-transition-timing-function', 'linear'); 583 el.css(slider.animProp, propValue); 584 // bind a callback method - executes when CSS transition completes 585 el.bind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){ 586 // unbind the callback 587 el.unbind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd'); 588 // reset the position 589 setPositionProperty(params['resetValue'], 'reset', 0); 590 // start the loop again 591 tickerLoop(); 592 }); 593 } 594 // use JS animate 595 }else{ 596 var animateObj = {}; 597 animateObj[slider.animProp] = value; 598 if(type == 'slide'){ 599 el.animate(animateObj, duration, slider.settings.easing, function(){ 600 updateAfterSlideTransition(); 601 }); 602 }else if(type == 'reset'){ 603 el.css(slider.animProp, value) 604 }else if(type == 'ticker'){ 605 el.animate(animateObj, speed, 'linear', function(){ 606 setPositionProperty(params['resetValue'], 'reset', 0); 607 // run the recursive loop after animation 608 tickerLoop(); 609 }); 610 } 611 } 612 }; 613 614 /** 615 * Populates the pager with proper amount of pages 616 */ 617 var populatePager = function(){ 618 var pagerHtml = ''; 619 var pagerQty = getPagerQty(); 620 // loop through each pager item 621 for(var i=0; i < pagerQty; i++){ 622 var linkContent = ''; 623 // if a buildPager function is supplied, use it to get pager link value, else use index + 1 624 if(slider.settings.buildPager && $.isFunction(slider.settings.buildPager)){ 625 linkContent = slider.settings.buildPager(i); 626 slider.pagerEl.addClass('bx-custom-pager'); 627 }else{ 628 linkContent = i + 1; 629 slider.pagerEl.addClass('bx-default-pager'); 630 } 631 // var linkContent = slider.settings.buildPager && $.isFunction(slider.settings.buildPager) ? slider.settings.buildPager(i) : i + 1; 632 // add the markup to the string 633 pagerHtml += '<li class="bx-pager-item"><a href="" data-slide-index="' + i + '" class="bx-pager-link">' + linkContent + '</a></li>'; 634 } 635 // populate the pager element with pager links 636 slider.pagerEl.html(pagerHtml); 637 }; 638 639 /** 640 * Appends the pager to the controls element 641 */ 642 var appendPager = function(){ 643 if(!slider.settings.pagerCustom){ 644 // create the pager DOM element 645 slider.pagerEl = $('<ul class="bx-pager" data-center="1" data-transform="0"/>'); 646 // if a pager selector was supplied, populate it with the pager 647 if(slider.settings.pagerSelector){ 648 $(slider.settings.pagerSelector).html(slider.pagerEl); 649 // if no pager selector was supplied, add it after the wrapper 650 }else{ 651 slider.controls.el.addClass('bx-has-pager').append(slider.pagerEl); 652 if(slider.settings.pagerType) { 653 slider.controls.el.addClass('thumbnails'); 654 } 655 } 656 // populate the pager 657 populatePager(); 658 }else{ 659 slider.pagerEl = $(slider.settings.pagerCustom); 660 } 661 // assign the pager click binding 662 slider.pagerEl.on('click', 'a', clickPagerBind); 663 }; 664 665 /** 666 * Appends prev / next controls to the controls element 667 */ 668 var appendControls = function(){ 669 slider.controls.next = $('<a class="bx-next" href="">' + slider.settings.nextText + '</a>'); 670 slider.controls.prev = $('<a class="bx-prev" href="">' + slider.settings.prevText + '</a>'); 671 // bind click actions to the controls 672 slider.controls.next.bind('click', clickNextBind); 673 slider.controls.prev.bind('click', clickPrevBind); 674 // if nextSlector was supplied, populate it 675 if(slider.settings.nextSelector){ 676 $(slider.settings.nextSelector).append(slider.controls.next); 677 } 678 // if prevSlector was supplied, populate it 679 if(slider.settings.prevSelector){ 680 $(slider.settings.prevSelector).append(slider.controls.prev); 681 } 682 // if no custom selectors were supplied 683 if(!slider.settings.nextSelector && !slider.settings.prevSelector){ 684 // add the controls to the DOM
vendor: 1,821 bytes, lines 685-718
685 slider.controls.directionEl = $('<div class="bx-controls-direction" />'); 686 // add the control elements to the directionEl 687 slider.controls.directionEl.append(slider.controls.prev).append(slider.controls.next); 688 // slider.viewport.append(slider.controls.directionEl); 689 slider.controls.el.addClass('bx-has-controls-direction').append(slider.controls.directionEl); 690 } 691 }; 692 693 /** 694 * Appends start / stop auto controls to the controls element 695 */ 696 var appendControlsAuto = function(){ 697 slider.controls.start = $('<div class="bx-controls-auto-item"><a class="bx-start" href="">' + slider.settings.startText + '</a></div>'); 698 slider.controls.stop = $('<div class="bx-controls-auto-item"><a class="bx-stop" href="">' + slider.settings.stopText + '</a></div>'); 699 // add the controls to the DOM 700 slider.controls.autoEl = $('<div class="bx-controls-auto" />'); 701 // bind click actions to the controls 702 slider.controls.autoEl.on('click', '.bx-start', clickStartBind); 703 slider.controls.autoEl.on('click', '.bx-stop', clickStopBind); 704 // if autoControlsCombine, insert only the "start" control 705 if(slider.settings.autoControlsCombine){ 706 slider.controls.autoEl.append(slider.controls.start); 707 // if autoControlsCombine is false, insert both controls 708 }else{ 709 slider.controls.autoEl.append(slider.controls.start).append(slider.controls.stop); 710 } 711 // if auto controls selector was supplied, populate it with the controls 712 if(slider.settings.autoControlsSelector){ 713 $(slider.settings.autoControlsSelector).html(slider.controls.autoEl); 714 // if auto controls selector was not supplied, add it after the wrapper 715 }else{ 716 slider.controls.el.addClass('bx-has-controls-auto').append(slider.controls.autoEl); 717 } 718 // update the auto controls
719 //updateAutoControls(slider.settings.autoStart ? 'stop' : 'start'); 720 }; 721 722 /** 723 * Appends image captions to the DOM 724 */ 725 var appendCaptions = function(){ 726 727 var htmlDecode = function(input){ 728 var e = document.createElement('div'); 729 e.innerHTML = input; 730 return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue; 731 }; 732 733 // cycle through each child 734 slider.children.each(function(index){ 735 // get the image title attribute 736 var image = $(this).find('img:first') 737 , title = image.length ? image.data('title') : $(this).attr('data-title'); 738 // append the caption 739 if (title != undefined && ('' + title).length) { 740 var captionPosition = slider.settings.inTop == true ? 'top' : ''; 741 742 $(this).append('<div class="bx-caption ' + captionPosition + '"><span class="caption"></span></div>'); 743 744 if(/<[a-z][\s\S]*>/i.test(htmlDecode(title))) { 745 title = $(htmlDecode(title)); 746 } 747 $(this).find('.caption').append(title); 748 //var padding = parseInt($(this).find('.bx-caption').css('padding'), 10); 749 //$(this).find('.bx-caption').css('width', (getSlideWidth() - 2*padding) + 'px'); 750 } 751 }); 752 }; 753 754 /** 755 * Click next binding 756 * 757 * @param e (event) 758 * - DOM event object 759 */ 760 var clickNextBind = function(e){ 761 // if auto show is running, stop it 762 if (slider.settings.auto) el.stopAuto(); 763 el.goToNextSlide(); 764 /*if(slider.settings.pagerType) { 765 pagerMoveLeft(); 766 }*/ 767 e.preventDefault(); 768 }; 769 770 /** 771 * Click prev binding 772 * 773 * @param e (event) 774 * - DOM event object 775 */ 776 var clickPrevBind = function(e){ 777 // if auto show is running, stop it 778 if (slider.settings.auto) el.stopAuto(); 779 el.goToPrevSlide(); 780 /*if(slider.settings.pagerType) { 781 pagerMoveRight(); 782 }*/ 783 e.preventDefault(); 784 }; 785 786 /** 787 * Click start binding 788 * 789 * @param e (event) 790 * - DOM event object 791 */ 792 var clickStartBind = function(e){ 793 slider.disabledAuto = false; 794 el.startAuto(); 795 e.preventDefault(); 796 }; 797 798 /** 799 * Click stop binding 800 * 801 * @param e (event) 802 * - DOM event object 803 */ 804 var clickStopBind = function(e){ 805 slider.disabledAuto = false; 806 el.stopAuto(); 807 e.preventDefault(); 808 }; 809 810 /** 811 * Click pager binding 812 * 813 * @param e (event) 814 * - DOM event object 815 */ 816 var clickPagerBind = function(e){ 817 // if auto show is running, stop it 818 if (slider.settings.auto) el.stopAuto(); 819 var pagerLink = $(e.currentTarget); 820 if(pagerLink.attr('data-slide-index') !== undefined){ 821 var pagerIndex = parseInt(pagerLink.attr('data-slide-index')); 822 // if clicked pager link is not active, continue with the goToSlide call 823 if(pagerIndex != slider.active.index) el.goToSlide(pagerIndex); 824 e.preventDefault(); 825 } 826 /*if(slider.settings.pagerType) { 827 pagerTranslate(this); 828 }*/ 829 }; 830 831 /*var pagerTranslate = function(self) { 832 var $pager = $('.bx-pager'); 833 834 if($(self).parent('li').index() > parseInt($pager.data('center'), 10)) { 835 $pager.data('center', parseInt($pager.data('center'), 10) + $pager.find('li').length - $(self).parent('li').index()); 836 }else { 837 $pager.data('center', parseInt($pager.data('center'), 10) - $pager.find('li').length - $(self).parent('li').index()); 838 } 839 }; 840 841 var thumbnailTranslate = function(element, translate, $pager) { 842 element.css({ 843 'transform': 'translateX(' + translate + 'px)', 844 '-webkit-transform': 'translateX(' + translate + 'px)', 845 '-moz-transform': 'translateX(' + translate + 'px)', 846 '-o-transform': 'translateX(' + translate + 'px)', 847 'transition': '0.4s', 848 '-webkit-transition': '0.4s', 849 '-moz-transition': '0.4s', 850 '-o-transition': '0.4s' 851 }); 852 853 $pager.data('transform', translate); 854 }; 855 856 var pagerMoveLeft = function() { 857 var $pager = $('.bx-pager'), 858 translate = $pager.data('transform'); 859 860 if(parseInt($pager.data('center')) < $pager.find('li').length - 3) { 861 translate -= slider.settings.slideWidth/4; 862 $pager.find('li').each(function() { 863 //translate = new WebKitCSSMatrix(translate).m41; 864 thumbnailTranslate($(this), translate, $pager); 865 }); 866 } 867 if(parseInt($pager.data('center')) == $pager.find('li').length) { 868 $pager.data('center', parseInt($pager.data('center'), 10) - $pager.find('li').length); 869 $pager.find('li').each(function() { 870 //translate = new WebKitCSSMatrix(translate).m41; 871 thumbnailTranslate($(this), Math.floor(slider.settings.slideWidth/4)*($pager.find('li').length - 5), $pager); 872 }); 873 } 874 875 $pager.data('center', parseInt($pager.data('center'), 10) + 1); 876 }; 877 878 var pagerMoveRight = function() { 879 var $pager = $('.bx-pager'), 880 translate = $pager.data('transform'); 881 882 if(parseInt($pager.data('center')) > 4 ) { 883 translate += slider.settings.slideWidth/4; 884 $pager.find('li').each(function() { 885 //translate = new WebKitCSSMatrix(translate).m41; 886 thumbnailTranslate($(this), translate, $pager); 887 }); 888 } 889 if(parseInt($pager.data('center')) == 1) { 890 $pager.data('center', parseInt($pager.data('center'), 10) + $pager.find('li').length); 891 $pager.find('li').each(function() { 892 //translate = new WebKitCSSMatrix(translate).m41; 893 thumbnailTranslate($(this), -Math.floor(slider.settings.slideWidth/4)*($pager.find('li').length - 4), $pager); 894 }); 895 } 896 897 $pager.data('center', parseInt($pager.data('center'), 10) - 1); 898 };*/ 899 900 /** 901 * Updates the pager links with an active class 902 * 903 * @param slideIndex (int) 904 * - index of slide to make active 905 */ 906 var updatePagerActive = function(slideIndex){ 907 // if "short" pager type 908 var len = slider.children.length; // nb of children 909 if(slider.settings.pagerType == 'short'){ 910 if(slider.settings.maxSlides > 1) { 911 len = Math.ceil(slider.children.length/slider.settings.maxSlides); 912 } 913 slider.pagerEl.html( (slideIndex + 1) + slider.settings.pagerShortSeparator + len); 914 return; 915 } 916 // remove all pager active classes 917 slider.pagerEl.find('a').removeClass('active'); 918 // apply the active class for all pagers 919 slider.pagerEl.each(function(i, el) { $(el).find('a').eq(slideIndex).addClass('active'); }); 920 }; 921 922 /** 923 * Performs needed actions after a slide transition 924 */ 925 var updateAfterSlideTransition = function(){ 926 // if infinte loop is true 927 if(slider.settings.infiniteLoop){ 928 var position = ''; 929 // first slide 930 if(slider.active.index == 0){ 931 // set the new position 932 position = slider.children.eq(0).position(); 933 // carousel, last slide 934 }else if(slider.active.index == getPagerQty() - 1 && slider.carousel){ 935 position = slider.children.eq((getPagerQty() - 1) * getMoveBy()).position(); 936 // last slide 937 }else if(slider.active.index == slider.children.length - 1){ 938 position = slider.children.eq(slider.children.length - 1).position(); 939 } 940 if(position){ 941 if (slider.settings.mode == 'horizontal') { setPositionProperty(-position.left, 'reset', 0); } 942 else if (slider.settings.mode == 'vertical') { setPositionProperty(-position.top, 'reset', 0); } 943 } 944 } 945 // declare that the transition is complete 946 slider.working = false; 947 // onSlideAfter callback 948 slider.settings.onSlideAfter(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); 949 }; 950 951 /** 952 * Updates the auto controls state (either active, or combined switch) 953 * 954 * @param state (string) "start", "stop" 955 * - the new state of the auto show 956 */ 957 var updateAutoControls = function(state){ 958 // if autoControlsCombine is true, replace the current control with the new state 959 if(slider.settings.autoControlsCombine){
960 slider.controls.autoEl.html(slider.controls[state]); 961 // if autoControlsCombine is false, apply the "active" class to the appropriate control 962 }else{ 963 slider.controls.autoEl.find('a').removeClass('active'); 964 slider.controls.autoEl.find('a:not(.bx-' + state + ')').addClass('active'); 965 } 966 }; 967 968 /** 969 * Updates the direction controls (checks if either should be hidden) 970 */ 971 var updateDirectionControls = function(){ 972 if(getPagerQty() == 1){ 973 slider.controls.prev.addClass('disabled'); 974 slider.controls.next.addClass('disabled'); 975 }else if(!slider.settings.infiniteLoop && slider.settings.hideControlOnEnd){ 976 // if first slide 977 if (slider.active.index == 0){ 978 slider.controls.prev.addClass('disabled'); 979 slider.controls.next.removeClass('disabled'); 980 // if last slide 981 }else if(slider.active.index == getPagerQty() - 1){ 982 slider.controls.next.addClass('disabled'); 983 slider.controls.prev.removeClass('disabled'); 984 // if any slide in the middle 985 }else{ 986 slider.controls.prev.removeClass('disabled'); 987 slider.controls.next.removeClass('disabled'); 988 } 989 } 990 }; 991 992 /** 993 * Initialzes the auto process 994 */ 995 var initAuto = function(){ 996 // if autoDelay was supplied, launch the auto show using a setTimeout() call 997 998 if(slider.settings.autoDelay > 0){ 999 var timeout = setTimeout(el.startAuto, slider.settings.autoDelay); 1000 // if autoDelay was not supplied, start the auto show normally 1001 }else{ 1002 el.startAuto(); 1003 } 1004 // if autoHover is requested 1005 if(slider.settings.autoHover){ 1006 // on el hover 1007 el.hover(function(){ 1008 // if the auto show is currently playing (has an active interval) 1009 if(slider.interval){ 1010 // stop the auto show and pass true agument which will prevent control update 1011 el.stopAuto(true); 1012 // create a new autoPaused value which will be used by the relative "mouseout" event 1013 slider.autoPaused = true; 1014 } 1015 }, function(){ 1016 // if the autoPaused value was created be the prior "mouseover" event 1017 if(slider.autoPaused){ 1018 // start the auto show and pass true agument which will prevent control update 1019 el.startAuto(true); 1020 // reset the autoPaused value 1021 slider.autoPaused = null; 1022 } 1023 }); 1024 } 1025 }; 1026 1027 /** 1028 * Initialzes the ticker process 1029 */ 1030 var initTicker = function(){ 1031 var startPosition = 0; 1032 // if autoDirection is "next", append a clone of the entire slider 1033 if(slider.settings.autoDirection == 'next'){ 1034 el.append(slider.children.clone().addClass('bx-clone')); 1035 // if autoDirection is "prev", prepend a clone of the entire slider, and set the left position 1036 }else{ 1037 el.prepend(slider.children.clone().addClass('bx-clone')); 1038 var position = slider.children.first().position(); 1039 startPosition = slider.settings.mode == 'horizontal' ? -position.left : -position.top; 1040 } 1041 setPositionProperty(startPosition, 'reset', 0); 1042 // do not allow controls in ticker mode 1043 slider.settings.pager = false; 1044 slider.settings.controls = false; 1045 slider.settings.autoControls = false; 1046 // if autoHover is requested 1047 if(slider.settings.tickerHover && !slider.usingCSS){ 1048 // on el hover 1049 slider.viewport.hover(function(){ 1050 el.stop(); 1051 }, function(){ 1052 // calculate the total width of children (used to calculate the speed ratio) 1053 var totalDimens = 0; 1054 slider.children.each(function(index){ 1055 totalDimens += slider.settings.mode == 'horizontal' ? $(this).outerWidth(true) : $(this).outerHeight(true); 1056 }); 1057 // calculate the speed ratio (used to determine the new speed to finish the paused animation) 1058 var ratio = slider.settings.speed / totalDimens; 1059 // determine which property to use 1060 var property = slider.settings.mode == 'horizontal' ? 'left' : 'top'; 1061 // calculate the new speed 1062 var newSpeed = ratio * (totalDimens - (Math.abs(parseInt(el.css(property))))); 1063 tickerLoop(newSpeed); 1064 }); 1065 } 1066 // start the ticker loop 1067 tickerLoop(); 1068 }; 1069 1070 /** 1071 * Runs a continuous loop, news ticker-style 1072 */ 1073 var tickerLoop = function(resumeSpeed){ 1074 speed = resumeSpeed ? resumeSpeed : slider.settings.speed; 1075 var position = {left: 0, top: 0};
1076 var reset = {left: 0, top: 0}; 1077 // if "next" animate left position to last child, then reset left to 0 1078 if(slider.settings.autoDirection == 'next'){ 1079 position = el.find('.bx-clone').first().position(); 1080 // if "prev" animate left position to 0, then reset left to first non-clone child 1081 }else{ 1082 reset = slider.children.first().position(); 1083 } 1084 var animateProperty = slider.settings.mode == 'horizontal' ? -position.left : -position.top; 1085 var resetValue = slider.settings.mode == 'horizontal' ? -reset.left : -reset.top; 1086 var params = {resetValue: resetValue}; 1087 setPositionProperty(animateProperty, 'ticker', speed, params); 1088 }; 1089 1090 /** 1091 * Initializes touch events 1092 */ 1093 var initTouch = function(){ 1094 // initialize object to contain all touch values 1095 slider.touch = { 1096 start: {x: 0, y: 0}, 1097 end: {x: 0, y: 0} 1098 }; 1099 slider.viewport.bind('touchstart', onTouchStart); 1100 }; 1101 1102 /** 1103 * Event handler for "touchstart" 1104 * 1105 * @param e (event) 1106 * - DOM event object 1107 */ 1108 var onTouchStart = function(e){ 1109 if(slider.working){ 1110 e.preventDefault(); 1111 }else{ 1112 // record the original position when touch starts 1113 slider.touch.originalPos = el.position(); 1114 var orig = e.originalEvent; 1115 // record the starting touch x, y coordinates 1116 slider.touch.start.x = orig.changedTouches[0].pageX; 1117 slider.touch.start.y = orig.changedTouches[0].pageY; 1118 // bind a "touchmove" event to the viewport 1119 slider.viewport.bind('touchmove', onTouchMove); 1120 // bind a "touchend" event to the viewport 1121 slider.viewport.bind('touchend', onTouchEnd); 1122 } 1123 }; 1124 1125 /** 1126 * Event handler for "touchmove" 1127 * 1128 * @param e (event) 1129 * - DOM event object 1130 */ 1131 var onTouchMove = function(e){ 1132 var orig = e.originalEvent; 1133 // if scrolling on y axis, do not prevent default 1134 var xMovement = Math.abs(orig.changedTouches[0].pageX - slider.touch.start.x); 1135 var yMovement = Math.abs(orig.changedTouches[0].pageY - slider.touch.start.y); 1136 // x axis swipe 1137 if((xMovement * 3) > yMovement && slider.settings.preventDefaultSwipeX){ 1138 e.preventDefault(); 1139 // y axis swipe 1140 }else if((yMovement * 3) > xMovement && slider.settings.preventDefaultSwipeY){ 1141 e.preventDefault(); 1142 } 1143 if(slider.settings.mode != 'fade' && slider.settings.oneToOneTouch){ 1144 var value = 0; 1145 var change; 1146 // if horizontal, drag along x axis 1147 if(slider.settings.mode == 'horizontal'){ 1148 change = orig.changedTouches[0].pageX - slider.touch.start.x; 1149 value = slider.touch.originalPos.left + change; 1150 // if vertical, drag along y axis 1151 }else{ 1152 change = orig.changedTouches[0].pageY - slider.touch.start.y; 1153 value = slider.touch.originalPos.top + change; 1154 } 1155 setPositionProperty(value, 'reset', 0); 1156 } 1157 }; 1158 1159 /** 1160 * Event handler for "touchend" 1161 * 1162 * @param e (event) 1163 * - DOM event object 1164 */ 1165 var onTouchEnd = function(e){ 1166 slider.viewport.unbind('touchmove', onTouchMove); 1167 var orig = e.originalEvent; 1168 var value = 0; 1169 var distance; 1170 // record end x, y positions 1171 slider.touch.end.x = orig.changedTouches[0].pageX; 1172 slider.touch.end.y = orig.changedTouches[0].pageY; 1173 // if fade mode, check if absolute x distance clears the threshold 1174 if(slider.settings.mode == 'fade'){ 1175 distance = Math.abs(slider.touch.start.x - slider.touch.end.x); 1176 if(distance >= slider.settings.swipeThreshold){ 1177 slider.touch.start.x > slider.touch.end.x ? el.goToNextSlide() : el.goToPrevSlide(); 1178 el.stopAuto(); 1179 } 1180 // not fade mode 1181 }else{ 1182 distance = 0; 1183 // calculate distance and el's animate property 1184 if(slider.settings.mode == 'horizontal'){ 1185 distance = slider.touch.end.x - slider.touch.start.x; 1186 value = slider.touch.originalPos.left; 1187 }else{ 1188 distance = slider.touch.end.y - slider.touch.start.y; 1189 value = slider.touch.originalPos.top; 1190 } 1191 // if not infinite loop and first / last slide, do not attempt a slide transition 1192 if(!slider.settings.infiniteLoop && ((slider.active.index == 0 && distance > 0) || (slider.active.last && distance < 0))){ 1193 setPositionProperty(value, 'reset', 200);
1194 }else{ 1195 // check if distance clears threshold 1196 if(Math.abs(distance) >= slider.settings.swipeThreshold){ 1197 distance < 0 ? el.goToNextSlide() : el.goToPrevSlide(); 1198 el.stopAuto(); 1199 }else{ 1200 // el.animate(property, 200); 1201 setPositionProperty(value, 'reset', 200); 1202 } 1203 } 1204 } 1205 slider.viewport.unbind('touchend', onTouchEnd); 1206 }; 1207 1208 /** 1209 * Window resize event callback 1210 */ 1211 var resizeWindow = function(e){ 1212 // don't do anything if slider isn't initialized. 1213 if(!slider.initialized) return; 1214 // get the new window dimens (again, thank you IE) 1215 var windowWidthNew = $(window).width(); 1216 var windowHeightNew = $(window).height(); 1217 // make sure that it is a true window resize 1218 // *we must check this because our dinosaur friend IE fires a window resize event when certain DOM elements 1219 // are resized. Can you just die already?* 1220 if(windowWidth != windowWidthNew || windowHeight != windowHeightNew){ 1221 // set the new window dimens 1222 windowWidth = windowWidthNew; 1223 windowHeight = windowHeightNew; 1224 // update all dynamic elements 1225 el.redrawSlider(); 1226 // Call user resize handler 1227 slider.settings.onSliderResize.call(el, slider.active.index); 1228 } 1229 }; 1230 1231 /** 1232 * =================================================================================== 1233 * = PUBLIC FUNCTIONS 1234 * =================================================================================== 1235 */ 1236 1237 /** 1238 * Performs slide transition to the specified slide 1239 * 1240 * @param slideIndex (int) 1241 * - the destination slide's index (zero-based) 1242 * 1243 * @param direction (string) 1244 * - INTERNAL USE ONLY - the direction of travel ("prev" / "next") 1245 */ 1246 el.goToSlide = function(slideIndex, direction){ 1247 // if plugin is currently in motion, ignore request 1248 if(slider.working || slider.active.index == slideIndex) return; 1249 // declare that plugin is in motion 1250 slider.working = true; 1251 // store the old index 1252 slider.oldIndex = slider.active.index; 1253 // if slideIndex is less than zero, set active index to last child (this happens during infinite loop) 1254 if(slideIndex < 0){ 1255 slider.active.index = getPagerQty() - 1; 1256 // if slideIndex is greater than children length, set active index to 0 (this happens during infinite loop) 1257 }else if(slideIndex >= getPagerQty()){ 1258 slider.active.index = 0; 1259 // set active index to requested slide 1260 }else{ 1261 slider.active.index = slideIndex; 1262 } 1263 // onSlideBefore, onSlideNext, onSlidePrev callbacks 1264 slider.settings.onSlideBefore(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); 1265 if(direction == 'next'){ 1266 slider.settings.onSlideNext(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); 1267 }else if(direction == 'prev'){ 1268 slider.settings.onSlidePrev(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); 1269 } 1270 // check if last slide 1271 slider.active.last = slider.active.index >= getPagerQty() - 1; 1272 // update the pager with active class 1273 if(slider.settings.pager) updatePagerActive(slider.active.index); 1274 // // check for direction control update 1275 if(slider.settings.controls) updateDirectionControls(); 1276 // if slider is set to mode: "fade" 1277 if(slider.settings.mode == 'fade'){ 1278 // if adaptiveHeight is true and next height is different from current height, animate to the new height 1279 if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHeight()){ 1280 slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed); 1281 } 1282 // fade out the visible child and reset its z-index value 1283 slider.children.filter(':visible').fadeOut(slider.settings.speed).css({zIndex: 0}); 1284 // fade in the newly requested slide 1285 slider.children.eq(slider.active.index).css('zIndex', slider.settings.slideZIndex+1).fadeIn(slider.settings.speed, function(){ 1286 $(this).css('zIndex', slider.settings.slideZIndex); 1287 updateAfterSlideTransition(); 1288 }); 1289 // slider mode is not "fade" 1290 }else{ 1291 // if adaptiveHeight is true and next height is different from current height, animate to the new height 1292 if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHe
1292ight()){ 1293 slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed); 1294 } 1295 var moveBy = 0; 1296 var position = {left: 0, top: 0}; 1297 // if carousel and not infinite loop 1298 if(!slider.settings.infiniteLoop && slider.carousel && slider.active.last){ 1299 if(slider.settings.mode == 'horizontal'){ 1300 // get the last child position 1301 var lastChild = slider.children.eq(slider.children.length - 1); 1302 position = lastChild.position(); 1303 // calculate the position of the last slide 1304 moveBy = slider.viewport.width() - lastChild.outerWidth(); 1305 }else{ 1306 // get last showing index position 1307 var lastShowingIndex = slider.children.length - slider.settings.minSlides; 1308 position = slider.children.eq(lastShowingIndex).position(); 1309 } 1310 // horizontal carousel, going previous while on first slide (infiniteLoop mode) 1311 }else if(slider.carousel && slider.active.last && direction == 'prev'){ 1312 // get the last child position 1313 var eq = slider.settings.moveSlides == 1 ? slider.settings.maxSlides - getMoveBy() : ((getPagerQty() - 1) * getMoveBy()) - (slider.children.length - slider.settings.maxSlides); 1314 var lastChild = el.children('.bx-clone').eq(eq); 1315 position = lastChild.position(); 1316 // if infinite loop and "Next" is clicked on the last slide 1317 }else if(direction == 'next' && slider.active.index == 0){ 1318 // get the last clone position 1319 position = el.find('> .bx-clone').eq(slider.settings.maxSlides).position(); 1320 slider.active.last = false; 1321 // normal non-zero requests 1322 }else if(slideIndex >= 0){ 1323 var requestEl = slideIndex * getMoveBy(); 1324 position = slider.children.eq(requestEl).position(); 1325 } 1326 1327 /* If the position doesn't exist 1328 * (e.g. if you destroy the slider on a next click), 1329 * it doesn't throw an error. 1330 */ 1331 if ("undefined" !== typeof(position)) { 1332 var value = slider.settings.mode == 'horizontal' ? -(position.left - moveBy) : -position.top; 1333 // plugin values to be animated 1334 setPositionProperty(value, 'slide', slider.settings.speed); 1335 } 1336 } 1337 }; 1338 1339 /** 1340 * Transitions to the next slide in the show 1341 */ 1342 el.goToNextSlide = function(){ 1343 // if infiniteLoop is false and last page is showing, disregard call 1344 if (!slider.settings.infiniteLoop && slider.active.last) return; 1345 var pagerIndex = parseInt(slider.active.index) + 1; 1346 el.goToSlide(pagerIndex, 'next'); 1347 }; 1348 1349 /** 1350 * Transitions to the prev slide in the show 1351 */ 1352 el.goToPrevSlide = function(){ 1353 // if infiniteLoop is false and last page is showing, disregard call 1354 if (!slider.settings.infiniteLoop && slider.active.index == 0) return; 1355 var pagerIndex = parseInt(slider.active.index) - 1; 1356 el.goToSlide(pagerIndex, 'prev'); 1357 }; 1358 1359 /** 1360 * Starts the auto show 1361 * 1362 * @param preventControlUpdate (boolean) 1363 * - if true, auto controls state will not be updated 1364 */ 1365 el.startAuto = function(preventControlUpdate){ 1366 // if an interval already exists, disregard call 1367 if(slider.interval || slider.disabledAuto === true) return; 1368 // create an interval 1369 slider.interval = setInterval(function(){ 1370 slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide(); 1371 }, slider.settings.pause); 1372 // if auto controls are displayed and preventControlUpdate is not true 1373 if (slider.settings.autoControls && preventControlUpdate != true ) updateAutoControls('stop'); 1374 }; 1375 1376 /** 1377 * Stops the auto show 1378 * 1379 * @param preventControlUpdate (boolean) 1380 * - if true, auto controls state will not be updated 1381 */ 1382 el.stopAuto = function(preventControlUpdate){ 1383 // if no interval exists, disregard call 1384 if(!slider.interval) return; 1385 // clear the interval 1386 clearInterval(slider.interval); 1387 slider.interval = null; 1388 // if auto controls are displayed and preventControlUpdate is not true 1389 if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('start'); 1390 }; 1391 1392 el.disableAuto = function(){ 1393 slider.disabledAuto = true; 1394 if (slider.settings.autoControls ) { 1395 updateAutoControls('start'); 1396 } 1397 }; 1398 1399 el.enableAuto = function(){ 1400 slider.disabledAuto = false; 1401 }; 1402 1403 /** 1404 * Returns current slide index (zero-based) 1405 */ 1406 el.getCurrentSlide = function(){ 1407 return slider.active.index; 1408 }; 1409 1410 /** 1411 * Returns current slide element 1412 */ 1413 el.getCurrentSlideElement = function(){ 1414 return slider.children.eq(slider.active.index); 1415 }; 1416 1417 /** 1418 * Returns number of slides in show 1419 */ 1420 el.getSlideCount = function(){ 1421 return slider.children.length; 1422 }; 1423 1424 /** 1425 * Update all dynamic slider elements 1426 */ 1427 el.redrawSlider = function(){ 1428 // resize all children in ratio to new screen size 1429 slider.children.add(el.find('.bx-clone')).width(getSlideWidth()); 1430 // adjust the height
1431 slider.viewport.css('height', getViewportHeight()); 1432 // update the slide position 1433 if(!slider.settings.ticker) setSlidePosition(); 1434 // if active.last was true before the screen resize, we want 1435 // to keep it last no matter what screen size we end on 1436 if (slider.active.last) slider.active.index = getPagerQty() - 1; 1437 // if the active index (page) no longer exists due to the resize, simply set the index as last 1438 if (slider.active.index >= getPagerQty()) slider.active.last = true; 1439 // if a pager is being displayed and a custom pager is not being used, update it 1440 if(slider.settings.pager && !slider.settings.pagerCustom){ 1441 //populatePager(); 1442 updatePagerActive(slider.active.index); 1443 } 1444 }; 1445 1446 /** 1447 * Destroy the current instance of the slider (revert everything back to original state) 1448 */ 1449 el.destroySlider = function(){ 1450 // don't do anything if slider has already been destroyed 1451 if(!slider.initialized) return; 1452 slider.initialized = false; 1453 $('.bx-clone', this).remove(); 1454 slider.children.each(function() { 1455 $(this).data("origStyle") != undefined ? $(this).attr("style", $(this).data("origStyle")) : $(this).removeAttr('style'); 1456 }); 1457 $(this).data("origStyle") != undefined ? this.attr("style", $(this).data("origStyle")) : $(this).removeAttr('style'); 1458 $(this).unwrap().unwrap(); 1459 if(slider.controls.el) slider.controls.el.remove(); 1460 if(slider.controls.next) slider.controls.next.remove(); 1461 if(slider.controls.prev) slider.controls.prev.remove(); 1462 if(slider.pagerEl && slider.settings.controls) slider.pagerEl.remove(); 1463 $('.bx-caption', this).remove(); 1464 if(slider.controls.autoEl) slider.controls.autoEl.remove(); 1465 clearInterval(slider.interval); 1466 if(slider.settings.responsive) $(window).unbind('resize', resizeWindow); 1467 }; 1468 1469 /** 1470 * Reload the slider (revert all DOM changes, and re-initialize) 1471 */ 1472 el.reloadSlider = function(settings){ 1473 if (settings != undefined) options = settings; 1474 el.destroySlider(); 1475 init(); 1476 }; 1477 1478 init(); 1479 1480 // returns the current jQuery object 1481 return this; 1482 } 1483 1484})(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.