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