1/* 2 * Ideal Image Slider v1.5.0 3 * 4 * By Gilbert Pellegrom 5 * http://gilbert.pellegrom.me 6 * 7 * Copyright (C) 2014 Dev7studios 8 * https://raw.githubusercontent.com/gilbitron/Ideal-Image-Slider/master/LICENSE 9 */ 10 11var IdealImageSlider = (function() { 12 "use strict"; 13 14 /* 15 * requestAnimationFrame polyfill 16 */ 17 var _requestAnimationFrame = function(win, t) { 18 return win["r" + t] || win["webkitR" + t] || win["mozR" + t] || win["msR" + t] || function(fn) { 19 setTimeout(fn, 1000 / 60); 20 }; 21 }(window, 'equestAnimationFrame'); 22 23 /** 24 * Behaves the same as setTimeout except uses requestAnimationFrame() where possible for better performance 25 * @param {function} fn The callback function 26 * @param {int} delay The delay in milliseconds 27 */ 28 var _requestTimeout = function(fn, delay) { 29 var start = new Date().getTime(), 30 handle = {}; 31 32 function loop() { 33 var current = new Date().getTime(), 34 delta = current - start; 35 36 if (delta >= delay) { 37 fn.call(); 38 } else { 39 handle.value = _requestAnimationFrame(loop); 40 } 41 } 42 43 handle.value = _requestAnimationFrame(loop); 44 return handle; 45 }; 46 47 /* 48 * Helper functions 49 */ 50 var _isType = function(type, obj) { 51 var _class = Object.prototype.toString.call(obj).slice(8, -1); 52 return obj !== undefined && obj !== null && _class === type; 53 }; 54 55 var _isInteger = function(x) { 56 return Math.round(x) === x; 57 }; 58 59 var _deepExtend = function(out) { 60 out = out || {}; 61 for (var i = 1; i < arguments.length; i++) { 62 var obj = arguments[i]; 63 if (!obj) 64 continue; 65 for (var key in obj) { 66 if (obj.hasOwnProperty(key)) { 67 if (_isType('Object', obj[key]) && obj[key] !== null) 68 _deepExtend(out[key], obj[key]); 69 else 70 out[key] = obj[key]; 71 } 72 } 73 } 74 return out; 75 }; 76 77 var _hasClass = function(el, className) { 78 if (!className) return false; 79 if (el.classList) { 80 return el.classList.contains(className); 81 } else { 82 return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className); 83 } 84 }; 85 86 var _addClass = function(el, className) { 87 if (!className) return; 88 if (el.classList) { 89 el.classList.add(className); 90 } else { 91 el.className += ' ' + className; 92 } 93 }; 94 95 var _removeClass = function(el, className) { 96 if (!className) return; 97 if (el.classList) { 98 el.classList.remove(className); 99 } else { 100 el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); 101 } 102 }; 103 104 var _toArray = function(obj) { 105 return Array.prototype.slice.call(obj); 106 }; 107 108 var _arrayRemove = function(array, from, to) { 109 var rest = array.slice((to || from) + 1 || array.length); 110 array.length = from < 0 ? array.length + from : from; 111 return array.push.apply(array, rest); 112 }; 113 114 var _addEvent = function(object, type, callback) { 115 if (object === null || typeof(object) === 'undefined') return; 116 117 if (object.addEventListener) { 118 object.addEventListener(type, callback, false); 119 } else if (object.attachEvent) { 120 object.attachEvent("on" + type, callback); 121 } else { 122 object["on" + type] = callback; 123 } 124 }; 125 126 var _loadImg = function(slide, callback) { 127 if (!slide.style.backgroundImage) { 128 var img = new Image(); 129 img.setAttribute('src', slide.getAttribute('data-src')); 130 img.onload = function() { 131 slide.style.backgroundImage = 'url(' + slide.getAttribute('data-src') + ')'; 132 slide.setAttribute('data-actual-width', this.naturalWidth); 133 slide.setAttribute('data-actual-height', this.naturalHeight); 134 if (typeof(callback) === 'function') callback(this); 135 }; 136 } 137 }; 138 139 var _isHighDPI = function() { 140 var mediaQuery = "(-webkit-min-device-pixel-ratio: 1.5),(min--moz-device-pixel-ratio: 1.5),(-o-min-device-pixel-ratio: 3/2),(min-resolution: 1.5dppx)"; 141 if (window.devicePixelRatio > 1) 142 return true; 143 if (window.matchMedia && window.matchMedia(mediaQuery).matches) 144 return true; 145 return false; 146 }; 147 148 var _translate = function(slide, dist, speed) { 149 slide.style.webkitTransitionDuration = 150 slide.style.MozTransitionDuration = 151 slide.style.msTransitionDuration = 152 slide.style.OTransitionDuration = 153 slide.style.transitionDuration = speed + 'ms'; 154 155 slide.style.webkitTransform = 156 slide.style.MozTransform = 157 slide.style.msTransform = 158 slide.style.OTransform = 'translateX(' + dist + 'px)'; 159 }; 160 161 var _unTranslate = function(slide) { 162 slide.style.removeProperty('-webkit-transition-duration'); 163 slide.style.removeProperty('transition-duration'); 164 165 slide.style.removeProperty('-webkit-transform'); 166 slide.style.removeProperty('-ms-transform'); 167 slide.style.removeProperty('transform'); 168 }; 169 170 var _animate = function(item) { 171 var duration = item.time, 172 end = +new Date() + duration; 173 174 var step = function() { 175 var current = +new Date(), 176 remaining = end - current; 177 178 if (remaining < 60) { 179 item.run(1); //1 = progress is at 100% 180 return; 181 } else { 182 var progress = 1 - remaining / duration; 183 item.run(progress); 184 } 185 186 _requestAnimationFrame(step); 187 }; 188 step(); 189 }; 190 191 var _setContainerHeight = function(slider, shouldAnimate) { 192 if (typeof shouldAnimate === 'undefined') { 193 shouldAnimate = true; 194 } 195 196 // If it's a fixed height then don't change the height 197 if (_isInteger(slider.settings.height)) { 198 return; 199 } 200
201 var currentHeight = Math.round(slider._attributes.container.offsetHeight), 202 newHeight = currentHeight; 203 204 if (slider._attributes.aspectWidth && slider._attributes.aspectHeight) { 205 // Aspect ratio 206 newHeight = (slider._attributes.aspectHeight / slider._attributes.aspectWidth) * slider._attributes.container.offsetWidth; 207 } else { 208 // Auto 209 var width = slider._attributes.currentSlide.getAttribute('data-actual-width'); 210 var height = slider._attributes.currentSlide.getAttribute('data-actual-height'); 211 212 if (width && height) { 213 newHeight = (height / width) * slider._attributes.container.offsetWidth; 214 } 215 } 216 217 var maxHeight = parseInt(slider.settings.maxHeight, 10); 218 if (maxHeight && newHeight > maxHeight) { 219 newHeight = maxHeight; 220 } 221 222 newHeight = Math.round(newHeight); 223 if (newHeight === currentHeight) { 224 return; 225 } 226 227 if (shouldAnimate) { 228 _animate({ 229 time: slider.settings.transitionDuration, 230 run: function(progress) { 231 slider._attributes.container.style.height = Math.round(progress * (newHeight - currentHeight) + currentHeight) + 'px'; 232 } 233 }); 234 } else { 235 slider._attributes.container.style.height = newHeight + 'px'; 236 } 237 }; 238 239 var _touch = { 240 241 vars: { 242 start: {}, 243 delta: {}, 244 isScrolling: undefined, 245 direction: null 246 }, 247 248 start: function(event) { 249 if (_hasClass(this._attributes.container, this.settings.classes.animating)) return; 250 251 var touches = event.touches[0]; 252 _touch.vars.start = { 253 x: touches.pageX, 254 y: touches.pageY, 255 time: +new Date() 256 }; 257 _touch.vars.delta = {}; 258 _touch.vars.isScrolling = undefined; 259 _touch.vars.direction = null; 260 261 this.stop(); // Stop slider 262 263 this.settings.beforeChange.apply(this); 264 _addClass(this._attributes.container, this.settings.classes.touching); 265 }, 266 267 move: function(event) { 268 if (_hasClass(this._attributes.container, this.settings.classes.animating)) return; 269 // Ensure swiping with one touch and not pinching 270 if (event.touches.length > 1 || event.scale && event.scale !== 1) return; 271 272 var touches = event.touches[0]; 273 _touch.vars.delta = { 274 x: touches.pageX - _touch.vars.start.x, 275 y: touches.pageY - _touch.vars.start.y 276 }; 277 278 if (typeof _touch.vars.isScrolling == 'undefined') { 279 _touch.vars.isScrolling = !!(_touch.vars.isScrolling || Math.abs(_touch.vars.delta.x) < Math.abs(_touch.vars.delta.y)); 280 } 281 282 // If user is not trying to scroll vertically 283 if (!_touch.vars.isScrolling) { 284 event.preventDefault(); // Prevent native scrolling 285 286 _translate(this._attributes.previousSlide, _touch.vars.delta.x - this._attributes.previousSlide.offsetWidth, 0); 287 _translate(this._attributes.currentSlide, _touch.vars.delta.x, 0); 288 _translate(this._attributes.nextSlide, _touch.vars.delta.x + this._attributes.currentSlide.offsetWidth, 0); 289 } 290 }, 291 292 end: function(event) { 293 if (_hasClass(this._attributes.container, this.settings.classes.animating)) return; 294 295 var duration = +new Date() - _touch.vars.start.time; 296 297 // Determine if slide attempt triggers next/prev slide 298 var isChangeSlide = Number(duration) < 250 && Math.abs(_touch.vars.delta.x) > 20 || Math.abs(_touch.vars.delta.x) > this._attributes.currentSlide.offsetWidth / 2; 299 300 var direction = _touch.vars.delta.x < 0 ? 'next' : 'previous'; 301 var speed = this.settings.transitionDuration ? this.settings.transitionDuration / 2 : 0; 302 303 // If not scrolling vertically 304 if (!_touch.vars.isScrolling) { 305 if (isChangeSlide) { 306 _touch.vars.direction = direction; 307 308 if (_touch.vars.direction == 'next') { 309 _translate(this._attributes.currentSlide, -this._attributes.currentSlide.offsetWidth, speed); 310 _translate(this._attributes.nextSlide, 0, speed); 311 } else { 312 _translate(this._attributes.previousSlide, 0, speed); 313 _translate(this._attributes.currentSlide, this._attributes.currentSlide.offsetWidth, speed); 314 } 315 316 _requestTimeout(_touch.transitionEnd.bind(this), speed); 317 } else { 318 // Slides return to original position 319 if (direction == 'next') { 320 _translate(this._attributes.currentSlide, 0, speed); 321 _translate(this._attributes.nextSlide, this._attributes.currentSlide.offsetWidth, speed); 322 } else { 323 _translate(this._attributes.previousSlide, -this._attributes.previousSlide.offsetWidth, speed); 324 _translate(this._attributes.currentSlide, 0, speed); 325 } 326 } 327 328 if (speed) { 329 _addClass(this._attributes.container, this.settings.classes.animating); 330 _requestTimeout(function() { 331 _removeClass(this._attributes.container, this.settings.classes.animating); 332 }.bind(this), speed); 333 } 334 } 335 }, 336 337 transitionEnd: function(event) { 338 if (_touch.vars.direction) { 339 _unTranslate(this._attributes.previousSlide); 340 _unTranslate(this._attributes.currentSlide); 341 _unTranslate(this._attributes.nextSlide); 342 _removeClass(this._attributes.container, this.settings.classes.touching); 343 344 _removeClass(this._attributes.previousSlide, this.settings.classes.previousSlide); 345 _removeClass(this._attributes.currentSlide, this.settings.classes.currentSlide); 346 _removeClass(this._attributes.nextSlide, this.settings.classes.nextSlide); 347 this._attributes.currentSlide.setAttribute('aria-hidden', 'true'); 348 349 var slides = this._attributes.slides, 350 index = slides.indexOf(this._attributes.currentSlide); 351 352 if (_touch.vars.direction == 'next') { 353 this._attributes.previousSlide = this._attributes.currentSlide; 354 this._attributes.currentSlide = slides[index + 1]; 355 this._attributes.nextSlide = slides[index + 2]; 356 if (typeof this._attributes.currentSlide === 'undefined' && 357 typeof this._attributes.nextSlide === 'undefined') { 358 this._attributes.currentSlide = slides[0]; 359 this._attributes.nextSlide = slides[1]; 360 } else { 361 if (typeof this._attributes.nextSlide === 'undefined') { 362 this._attributes.nextSlide = slides[0]; 363 } 364 } 365 366 _loadImg(this._attributes.nextSlide); 367 } else { 368 this._attributes.nextSlide = this._attributes.currentSlide; 369 this._attributes.previousSlide = slides[index - 2]; 370 this._attributes.currentSlide = slides[index - 1]; 371 if (typeof this._attributes.currentSlide === 'undefined' && 372 typeof this._attributes.previousSlide === 'undefined') { 373 this._attributes.currentSlide = slides[slides.length - 1]; 374 this._attributes.previousSlide = slides[slides.length - 2]; 375 } else { 376 if (typeof this._attributes.previousSlide === 'undefined') { 377 this._attributes.previousSlide = slides[slides.length - 1]; 378 } 379 } 380 381 _loadImg(this._attributes.previousSlide); 382 } 383 384 _addClass(this._attributes.previousSlide, this.settings.classes.previousSlide); 385 _addClass(this._attributes.currentSlide, this.settings.classes.currentSlide); 386 _addClass(this._attributes.nextSlide, this.settings.classes.nextSlide); 387 this._attributes.currentSlide.setAttribute('aria-hidden', 'false'); 388 389 _setContainerHeight(this); 390 this.settings.afterChange.apply(this); 391 } 392 } 393 394 }; 395 396 /* 397 * Slider class 398 */ 399 var Slider = function(args) { 400 // Defaults 401 this.settings = { 402 selector: '', 403 height: 'auto', // "auto" | px value (e.g. 400) | aspect ratio (e.g. "16:9") 404 initialHeight: 400, // for "auto" and aspect ratio 405 maxHeight: null, // for "auto" and aspect ratio 406 interval: 4000, 407 transitionDuration: 700, 408 effect: 'slide', 409 disableNav: false, 410 keyboardNav: true, 411 previousNavSelector: '', 412 nextNavSelector: '', 413 classes: { 414 container: 'ideal-image-slider', 415 slide: 'iis-slide', 416 previousSlide: 'iis-previous-slide', 417 currentSlide: 'iis-current-slide', 418 nextSlide: 'iis-next-slide', 419 previousNav: 'iis-previous-nav', 420 nextNav: 'iis-next-nav', 421 animating: 'iis-is-animating', 422 touchEnabled: 'iis-touch-enabled', 423 touching: 'iis-is-touching',
424 directionPrevious: 'iis-direction-previous', 425 directionNext: 'iis-direction-next' 426 }, 427 onInit: function() {}, 428 onStart: function() {}, 429 onStop: function() {}, 430 onDestroy: function() {}, 431 beforeChange: function() {}, 432 afterChange: function() {} 433 }; 434 435 // Parse args 436 if (typeof args === 'string') { 437 this.settings.selector = args; 438 } else if (typeof args === 'object') { 439 _deepExtend(this.settings, args); 440 } 441 442 // Slider (container) element 443 var sliderEl = document.querySelector(this.settings.selector); 444 if (!sliderEl) return null; 445 446 // Slides 447 var origChildren = _toArray(sliderEl.children), 448 validSlides = []; 449 sliderEl.innerHTML = ''; 450 Array.prototype.forEach.call(origChildren, function(slide, i) { 451 if (slide instanceof HTMLImageElement || slide instanceof HTMLAnchorElement) { 452 var slideEl = document.createElement('a'), 453 href = '', 454 target = ''; 455 456 if (slide instanceof HTMLAnchorElement) { 457 href = slide.getAttribute('href'); 458 target = slide.getAttribute('target'); 459 460 var img = slide.querySelector('img'); 461 if (img !== null) { 462 slide = img; 463 } else { 464 return; 465 } 466 } 467 468 if (typeof slide.dataset !== 'undefined') { 469 _deepExtend(slideEl.dataset, slide.dataset); 470 if (slide.dataset.src) { 471 // Use data-src for on-demand loading 472 slideEl.dataset.src = slide.dataset.src; 473 } else { 474 slideEl.dataset.src = slide.src; 475 } 476 477 // HiDPI support 478 if (_isHighDPI() && slide.dataset['src-2x']) { 479 slideEl.dataset.src = slide.dataset['src-2x']; 480 } 481 } else { 482 // IE 483 if (slide.getAttribute('data-src')) { 484 slideEl.setAttribute('data-src', slide.getAttribute('data-src')); 485 } else { 486 slideEl.setAttribute('data-src', slide.getAttribute('src')); 487 } 488 } 489 490 if (href) slideEl.setAttribute('href', href); 491 if (target) slideEl.setAttribute('target', target); 492 if (slide.getAttribute('className')) _addClass(slideEl, slide.getAttribute('className')); 493 if (slide.getAttribute('id')) slideEl.setAttribute('id', slide.getAttribute('id')); 494 if (slide.getAttribute('title')) slideEl.setAttribute('title', slide.getAttribute('title')); 495 if (slide.getAttribute('link')) slideEl.setAttribute('link', slide.getAttribute('link')); 496 if (slide.getAttribute('alt')) slideEl.innerHTML = slide.getAttribute('alt'); 497 slideEl.setAttribute('role', 'tabpanel'); 498 slideEl.setAttribute('aria-hidden', 'true'); 499 500 slideEl.style.cssText += '-webkit-transition-duration:' + this.settings.transitionDuration + 'ms;-moz-transition-duration:' + this.settings.transitionDuration + 'ms;-o-transition-duration:' + this.settings.transitionDuration + 'ms;transition-duration:' + this.settings.transitionDuration + 'ms;'; 501 502 sliderEl.appendChild(slideEl); 503 validSlides.push(slideEl); 504 } 505 }.bind(this)); 506 507 var slides = validSlides; 508 if (slides.length <= 1) { 509 sliderEl.innerHTML = ''; 510 Array.prototype.forEach.call(origChildren, function(child, i) { 511 sliderEl.appendChild(child); 512 }); 513 return null; 514 } 515 516 // Create navigation 517 if (!this.settings.disableNav) { 518 var previousNav, nextNav; 519 if (this.settings.previousNavSelector) { 520 previousNav = document.querySelector(this.settings.previousNavSelector); 521 } else { 522 previousNav = document.createElement('a'); 523 sliderEl.appendChild(previousNav); 524 } 525 if (this.settings.nextNavSelector) { 526 nextNav = document.querySelector(this.settings.nextNavSelector); 527 } else { 528 nextNav = document.createElement('a'); 529 sliderEl.appendChild(nextNav); 530 } 531 532 _addClass(previousNav, this.settings.classes.previousNav); 533 _addClass(nextNav, this.settings.classes.nextNav); 534 _addEvent(previousNav, 'click', function() { 535 if (_hasClass(this._attributes.container, this.settings.classes.animating)) return false; 536 this.stop(); 537 this.previousSlide(); 538 }.bind(this)); 539 _addEvent(nextNav, 'click', function() { 540 if (_hasClass(this._attributes.container, this.settings.classes.animating)) return false; 541 this.stop(); 542 this.nextSlide(); 543 }.bind(this)); 544 545 // Touch Navigation 546 if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) { 547 this.settings.effect = 'slide'; 548 previousNav.style.display = 'none'; 549 nextNav.style.display = 'none'; 550 _addClass(sliderEl, this.settings.classes.touchEnabled); 551 552 _addEvent(sliderEl, 'touchstart', _touch.start.bind(this), false); 553 _addEvent(sliderEl, 'touchmove', _touch.move.bind(this), false); 554 _addEvent(sliderEl, 'touchend', _touch.end.bind(this), false); 555 } 556 557 // Keyboard Navigation 558 if (this.settings.keyboardNav) { 559 _addEvent(document, 'keyup', function(e) { 560 e = e || window.event; 561 var button = (typeof e.which == 'number') ? e.which : e.keyCode; 562 if (button == 37) { 563 if (_hasClass(this._attributes.container, this.settings.classes.animating)) return false;
564 this.stop(); 565 this.previousSlide(); 566 } else if (button == 39) { 567 if (_hasClass(this._attributes.container, this.settings.classes.animating)) return false; 568 this.stop(); 569 this.nextSlide(); 570 } 571 }.bind(this)); 572 } 573 } 574 575 // Create internal attributes 576 this._attributes = { 577 container: sliderEl, 578 slides: slides, 579 previousSlide: typeof slides[slides.length - 1] !== 'undefined' ? slides[slides.length - 1] : slides[0], 580 currentSlide: slides[0], 581 nextSlide: typeof slides[1] !== 'undefined' ? slides[1] : slides[0], 582 timerId: 0, 583 origChildren: origChildren, // Used in destroy() 584 aspectWidth: 0, 585 aspectHeight: 0 586 }; 587 588 // Set height 589 if (_isInteger(this.settings.height)) { 590 this._attributes.container.style.height = this.settings.height + 'px'; 591 } else { 592 if (_isInteger(this.settings.initialHeight)) { 593 this._attributes.container.style.height = this.settings.initialHeight + 'px'; 594 } 595 596 // If aspect ratio parse and store 597 if (this.settings.height.indexOf(':') > -1) { 598 var aspectRatioParts = this.settings.height.split(':'); 599 if (aspectRatioParts.length == 2 && _isInteger(parseInt(aspectRatioParts[0], 10)) && _isInteger(parseInt(aspectRatioParts[1], 10))) { 600 this._attributes.aspectWidth = parseInt(aspectRatioParts[0], 10); 601 this._attributes.aspectHeight = parseInt(aspectRatioParts[1], 10); 602 } 603 } 604 605 _addEvent(window, 'resize', function() { 606 _setContainerHeight(this, false); 607 }.bind(this)); 608 } 609 610 // Add classes 611 _addClass(sliderEl, this.settings.classes.container); 612 _addClass(sliderEl, 'iis-effect-' + this.settings.effect); 613 Array.prototype.forEach.call(this._attributes.slides, function(slide, i) { 614 _addClass(slide, this.settings.classes.slide); 615 }.bind(this)); 616 _addClass(this._attributes.previousSlide, this.settings.classes.previousSlide); 617 _addClass(this._attributes.currentSlide, this.settings.classes.currentSlide); 618 _addClass(this._attributes.nextSlide, this.settings.classes.nextSlide); 619 620 // ARIA 621 this._attributes.currentSlide.setAttribute('aria-hidden', 'false'); 622 623 // Load first image 624 _loadImg(this._attributes.currentSlide, (function() { 625 this.settings.onInit.apply(this); 626 _setContainerHeight(this, false); 627 }).bind(this)); 628 // Preload next images 629 _loadImg(this._attributes.previousSlide); 630 _loadImg(this._attributes.nextSlide); 631 }; 632 633 Slider.prototype.get = function(attribute) { 634 if (!this._attributes) return null; 635 if (this._attributes.hasOwnProperty(attribute)) { 636 return this._attributes[attribute]; 637 } 638 }; 639 640 Slider.prototype.set = function(attribute, value) { 641 if (!this._attributes) return null; 642 return (this._attributes[attribute] = value); 643 }; 644 645 Slider.prototype.start = function() { 646 if (!this._attributes) return; 647 this._attributes.timerId = setInterval(this.nextSlide.bind(this), this.settings.interval); 648 this.settings.onStart.apply(this); 649 650 // Stop if window blur 651 window.onblur = function() { 652 this.stop(); 653 }.bind(this); 654 }; 655 656 Slider.prototype.stop = function() { 657 if (!this._attributes) return; 658 clearInterval(this._attributes.timerId); 659 this._attributes.timerId = 0; 660 this.settings.onStop.apply(this); 661 }; 662 663 Slider.prototype.previousSlide = function() { 664 this.settings.beforeChange.apply(this); 665 _removeClass(this._attributes.previousSlide, this.settings.classes.previousSlide); 666 _removeClass(this._attributes.currentSlide, this.settings.classes.currentSlide); 667 _removeClass(this._attributes.nextSlide, this.settings.classes.nextSlide); 668 this._attributes.currentSlide.setAttribute('aria-hidden', 'true'); 669 670 var slides = this._attributes.slides, 671 index = slides.indexOf(this._attributes.currentSlide); 672 this._attributes.nextSlide = this._attributes.currentSlide; 673 this._attributes.previousSlide = slides[index - 2]; 674 this._attributes.currentSlide = slides[index - 1]; 675 if (typeof this._attributes.currentSlide === 'undefined' && 676 typeof this._attributes.previousSlide === 'undefined') { 677 this._attributes.currentSlide = slides[slides.length - 1]; 678 this._attributes.previousSlide = slides[slides.length - 2]; 679 } else { 680 if (typeof this._attributes.previousSlide === 'undefined') { 681 this._attributes.previousSlide = slides[slides.length - 1]; 682 } 683 } 684 685 // Preload next image 686 _loadImg(this._attributes.previousSlide); 687 688 _addClass(this._attributes.previousSlide, this.settings.classes.previousSlide); 689 _addClass(this._attributes.currentSlide, this.settings.classes.currentSlide); 690 _addClass(this._attributes.nextSlide, this.settings.classes.nextSlide); 691 this._attributes.currentSlide.setAttribute('aria-hidden', 'false'); 692 693 _addClass(this._attributes.container, this.settings.classes.directionPrevious); 694 _requestTimeout(function() { 695 _removeClass(this._attributes.container, this.settings.classes.directionPrevious); 696 }.bind(this), this.settings.transitionDuration); 697 698 if (this.settings.transitionDuration) { 699 _addClass(this._attributes.container, this.settings.classes.animating); 700 _requestTimeout(function() { 701 _removeClass(this._attributes.container, this.settings.classes.animating); 702 }.bind(this), this.settings.transitionDuration); 703 } 704 705 _setContainerHeight(this); 706 this.settings.afterChange.apply(this); 707 }; 708 709 Slider.prototype.nextSlide = function() { 710 this.settings.beforeChange.apply(this); 711 _removeClass(this._attributes.previousSlide, this.settings.classes.previousSlide); 712 _removeClass(this._attributes.currentSlide, this.settings.classes.currentSlide); 713 _removeClass(this._attributes.nextSlide, this.settings.classes.nextSlide); 714 this._attributes.currentSlide.setAttribute('aria-hidden', 'true'); 715 716 var slides = this._attributes.slides, 717 index = slides.indexOf(this._attributes.currentSlide); 718 this._attributes.previousSlide = this._attributes.currentSlide; 719 this._attributes.currentSlide = slides[index + 1]; 720 this._attributes.nextSlide = slides[index + 2]; 721 if (typeof this._attributes.currentSlide === 'undefined' && 722 typeof this._attributes.nextSlide === 'undefined') { 723 this._attributes.currentSlide = slides[0]; 724 this._attributes.nextSlide = slides[1]; 725 } else { 726 if (typeof this._attributes.nextSlide === 'undefined') { 727 this._attributes.nextSlide = slides[0]; 728 } 729 } 730 731 // Preload next image 732 _loadImg(this._attributes.nextSlide); 733 734 _addClass(this._attributes.previousSlide, this.settings.classes.previousSlide); 735 _addClass(this._attributes.currentSlide, this.settings.classes.currentSlide); 736 _addClass(this._attributes.nextSlide, this.settings.classes.nextSlide); 737 this._attributes.currentSlide.setAttribute('aria-hidden', 'false'); 738 739 _addClass(this._attributes.container, this.settings.classes.directionNext); 740 _requestTimeout(function() { 741 _removeClass(this._attributes.container, this.settings.classes.directionNext); 742 }.bind(this), this.settings.transitionDuration); 743 744 if (this.settings.transitionDuration) { 745 _addClass(this._attributes.container, this.settings.classes.animating); 746 _requestTimeout(function() { 747 _removeClass(this._attributes.container, this.settings.classes.animating); 748 }.bind(this), this.settings.transitionDuration); 749 } 750 751 _setContainerHeight(this); 752 this.settings.afterChange.apply(this); 753 }; 754
755 Slider.prototype.gotoSlide = function(index) { 756 this.settings.beforeChange.apply(this); 757 this.stop(); 758 759 _removeClass(this._attributes.previousSlide, this.settings.classes.previousSlide); 760 _removeClass(this._attributes.currentSlide, this.settings.classes.currentSlide); 761 _removeClass(this._attributes.nextSlide, this.settings.classes.nextSlide); 762 this._attributes.currentSlide.setAttribute('aria-hidden', 'true'); 763 764 index--; // Index should be 1-indexed 765 var slides = this._attributes.slides, 766 oldIndex = slides.indexOf(this._attributes.currentSlide); 767 this._attributes.previousSlide = slides[index - 1]; 768 this._attributes.currentSlide = slides[index]; 769 this._attributes.nextSlide = slides[index + 1]; 770 if (typeof this._attributes.previousSlide === 'undefined') { 771 this._attributes.previousSlide = slides[slides.length - 1]; 772 } 773 if (typeof this._attributes.nextSlide === 'undefined') { 774 this._attributes.nextSlide = slides[0]; 775 } 776 777 // Load images 778 _loadImg(this._attributes.previousSlide); 779 _loadImg(this._attributes.currentSlide); 780 _loadImg(this._attributes.nextSlide); 781 782 _addClass(this._attributes.previousSlide, this.settings.classes.previousSlide); 783 _addClass(this._attributes.currentSlide, this.settings.classes.currentSlide); 784 _addClass(this._attributes.nextSlide, this.settings.classes.nextSlide); 785 this._attributes.currentSlide.setAttribute('aria-hidden', 'false'); 786 787 if (index < oldIndex) { 788 _addClass(this._attributes.container, this.settings.classes.directionPrevious); 789 _requestTimeout(function() { 790 _removeClass(this._attributes.container, this.settings.classes.directionPrevious); 791 }.bind(this), this.settings.transitionDuration); 792 } else { 793 _addClass(this._attributes.container, this.settings.classes.directionNext); 794 _requestTimeout(function() { 795 _removeClass(this._attributes.container, this.settings.classes.directionNext); 796 }.bind(this), this.settings.transitionDuration); 797 } 798 799 if (this.settings.transitionDuration) { 800 _addClass(this._attributes.container, this.settings.classes.animating); 801 _requestTimeout(function() { 802 _removeClass(this._attributes.container, this.settings.classes.animating); 803 }.bind(this), this.settings.transitionDuration); 804 } 805 806 _setContainerHeight(this); 807 this.settings.afterChange.apply(this); 808 }; 809 810 Slider.prototype.destroy = function() { 811 clearInterval(this._attributes.timerId); 812 this._attributes.timerId = 0; 813 814 this._attributes.container.innerHTML = ''; 815 Array.prototype.forEach.call(this._attributes.origChildren, function(child, i) { 816 this._attributes.container.appendChild(child); 817 }.bind(this)); 818 819 _removeClass(this._attributes.container, this.settings.classes.container); 820 _removeClass(this._attributes.container, 'iis-effect-' + this.settings.effect); 821 this._attributes.container.style.height = ''; 822 823 this.settings.onDestroy.apply(this); 824 }; 825 826 return { 827 _hasClass: _hasClass, 828 _addClass: _addClass, 829 _removeClass: _removeClass, 830 Slider: Slider 831 }; 832 833})();
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.