1/** 2* Really Simple⢠Slideshow jQuery plug-in 1.4.12 3* --------------------------------------------------------- 4* Load slideshow images dynamically, instead of all at once 5* --------------------------------------------------------- 6* 7* Introduction, Demos, Docs and Downloads: 8* http://reallysimpleworks.com/slideshow 9* 10* Copyright (c) 2011 Really Simple 11* http://reallysimpleworks.com 12* 13* Licensed under the MIT license: 14* http://www.opensource.org/licenses/mit-license.php 15* Free to use for both commercial and non-commercial. 16*/ 17 18 19/** 20* Extra Bite-Sized Docs 21* --------------------- 22* 23* If embedding slide data in your markup, you can initialise 24* and start a slideshow with one line of code: 25* 26* $('#my-slideshow-div').rsfSlideshow(); 27* 28* If you're pulling in slide data from elsewhere and want to 29* manually add slides to the slideshow: 30* 31* var slides = Array( 32* {url: 'http://mydomain.com/images/1.png', caption: 'This is slide number 1'}, 33* {url: 'http://mydomain.com/images/2.png', caption: 'This is slide number 2', captionClass: 'highlight'}, 34* {url: '/images/3.png', caption: 'This is slide number 3'}, 35* ); 36* $('#my-slideshow-div').rsfSlideshow({slides: slides}); 37* 38* For complete docs and demos, visit: 39* http://reallysimpleworks.com/slideshow 40*/ 41 42 43 44 45 46(function($) { 47 48 49 var methods = { 50 51 52 /** 53 * The 'options' object can be used to override any of the 54 * default parameters in the 'defaults' object above 55 */ 56 57 init: function(options) { 58 59 return this.each(function() { 60 61 var slideshow = this, 62 $slideshow = $(this), 63 data = $slideshow.data('rsf_slideshow'), 64 settings; 65 66 if (!data) { 67 settings = $.extend(true, {}, $.rsfSlideshow.defaults); 68 if (typeof options === 'object') { 69 $.extend(true, settings, options); 70 } 71 $slideshow.data('rsf_slideshow', { 72 slides: [], 73 this_slide: 0, 74 effect_iterator: { 75 this_effect: -1, 76 direction: 1 77 }, 78 settings: settings, 79 interval_id: false, 80 loaded_imgs: [], 81 queued: 0 82 }); 83 data = $slideshow.data('rsf_slideshow'); 84 } 85 settings = data.settings; 86 87 88 // Attempt to find slide data in the page markup 89 $slideshow.rsfSlideshow('getSlidesFromMarkup'); 90 91 92 // Add slide data from an array, if provided 93 if (settings.slides.length) { 94 $slideshow.rsfSlideshow('addSlides', settings.slides); 95 settings.slides = []; 96 } 97 98 99 // Bind gloabal slidshow event handlers 100 if (typeof settings.eventHandlers === 'object') { 101 $.each(settings.eventHandlers, function(evnt, fn) { 102 $slideshow.bind(evnt, function(e) {fn($slideshow, e); }); 103 }); 104 } 105 106 107 // Generate and bind control elements 108 if (settings.controls.playPause.auto) { 109 $slideshow.rsfSlideshow('addControl', 'playPause'); 110 } 111 if (settings.controls.previousSlide.auto) { 112 $slideshow.rsfSlideshow('addControl', 'previousSlide'); 113 } 114 if (settings.controls.index.auto) { 115 $slideshow.rsfSlideshow('addControl', 'index'); 116 } 117 if (settings.controls.nextSlide.auto) { 118 $slideshow.rsfSlideshow('addControl', 'nextSlide'); 119 } 120 121 122 // Start the slideshow 123 if (settings.autostart) { 124 $slideshow.rsfSlideshow('startShow'); 125 } 126 127 }); 128 }, 129 130 131 /** 132 * Add slide data to the slideshow 133 * @param slides (required) object, array or string 134 * a string containing the URL of the slide image or 135 * a slide object containing the properties for a single 136 * slide (see docs) or 137 * an array of slide objects 138 */ 139 140 addSlides: function(slides) { 141 return this.each(function() { 142 if (slides instanceof Array) { 143 for (var i = 0, len = slides.length; i < len; i ++) { 144 RssPrivateMethods._addSlide($(this), slides[i]); 145 } 146 } 147 else { 148 RssPrivateMethods._addSlide($(this), slides); 149 } 150 }); 151 }, 152 153 154 /** 155 * Remove slide(s) from the slideshow 156 * @param slide_keys (optional) array or integer 157 * an array of slide indices to remove from the slides array or 158 * a single slide index as an integer 159 * if not set, the whole slides array is emptied 160 */ 161 162 removeSlides: function(slide_keys) { 163 if (slide_keys === undefined) { 164 return this.each(function() { 165 $(this).data('rsf_slideshow').slides = []; 166 }); 167 } 168 else if (slide_keys instanceof Array) { 169 slide_keys.sort(function(a, b) {return b - a; }); 170 var removed = []; 171 return this.each(function() { 172 for (var i = 0, len = slide_keys.length; i < len; i ++) { 173 if ($.inArray(slide_keys[i], removed) === -1) { 174 RssPrivateMethods._removeSlide($(this), slide_keys[i]); 175 removed.push(slide_keys[i]); 176 } 177 } 178 }); 179 } 180 else { 181 return this.each(function() { 182 RssPrivateMethods._removeSlide($(this), slide_keys); 183 }); 184 } 185 }, 186 187 188 /** 189 * Returns a slide data object by key, or the 190 * entire slides array if a key is not specified 191 * @param key (optional) integer 192 * the index of a slide in the slide array 193 */ 194
195 getSlideData: function(key) { 196 if (key === undefined) { 197 return this.data('rsf_slideshow').slides; 198 } 199 if (this.data('rsf_slideshow').slides[key]) { 200 return this.data('rsf_slideshow').slides[key]; 201 } 202 return false; 203 }, 204 205 206 /** 207 * Start the slideshow 208 * @param interval (optional) integer or float 209 * the duration for which each slide is displayed 210 * if set, this overrides the options setting 211 * @param instant (optional) boolean 212 * if true, the first transition is triggered immediately 213 */ 214 215 startShow: function(interval, instant) { 216 return this.each(function() { 217 var $slideshow = $(this); 218 if (!$slideshow.data('rsf_slideshow').interval_id) { 219 if (instant) { 220 $slideshow.rsfSlideshow('nextSlide'); 221 } 222 $slideshow.data('rsf_slideshow')._current_interval = interval; 223 RssPrivateMethods._setTimeout($slideshow, interval); 224 $slideshow.bind('_rsSlideReady', function(e, event_data) { 225 RssPrivateMethods._setTimeout($slideshow, interval); 226 }); 227 RssPrivateMethods._trigger($slideshow, 'rsStartShow'); 228 } 229 }); 230 }, 231 232 233 /** 234 * Stop the slideshow 235 */ 236 237 stopShow: function() { 238 return this.each(function() { 239 var $slideshow = $(this), 240 data = $slideshow.data('rsf_slideshow'); 241 if (data.interval_id) { 242 clearTimeout(data.interval_id); 243 data.interval_id = false; 244 } 245 $slideshow.unbind('_rsSlideReady'); 246 RssPrivateMethods._trigger($(this), 'rsStopShow'); 247 }); 248 }, 249 250 251 /** 252 * Toggle the slideshow 253 * calls startShow if the slideshow is stopped 254 * and stopShow if it is running 255 */ 256 257 toggleShow: function() { 258 return this.each(function() { 259 if ($(this).rsfSlideshow('isRunning')) { 260 $(this).rsfSlideshow('stopShow'); 261 } 262 else { 263 $(this).rsfSlideshow('startShow', false, true); 264 } 265 }); 266 }, 267 268 269 /** 270 * Returns true if the slideshow is currently 271 * running, false if not. 272 */ 273 274 isRunning: function() { 275 if (this.data('rsf_slideshow').interval_id) { 276 return true; 277 } 278 return false; 279 }, 280 281 282 /** 283 * Return the array key of the current slide 284 * The first slide's key is 0. 285 */ 286 287 currentSlideKey: function() { 288 var data = this.data('rsf_slideshow'); 289 return data.this_slide; 290 }, 291 292 293 /** 294 * Return the total number of slides currently in the slideshow 295 */ 296 297 totalSlides: function() { 298 var data = this.data('rsf_slideshow'); 299 return data.slides.length; 300 }, 301 302 303 /** 304 * Find slide data in the markup and add to the slides array 305 * @param options (optional) object 306 * an object containing options to override default settings for: 307 * data_container 308 * slide_data_container 309 * slide_data_selectors 310 * (see default options and docs) 311 */ 312 313 getSlidesFromMarkup: function(options) { 314 return this.each(function() { 315 var data = $(this).data('rsf_slideshow'); 316 if (!options) { 317 options = {}; 318 } 319 // Find the containing element 320 if (!options.data_container) { 321 options.data_container = data.settings.data_container; 322 } 323 var $cntnr; 324 if (options.data_container.charAt(0) === '#') { 325 $cntnr = $(options.data_container); 326 } 327 else { 328 $cntnr = $(this).children(options.data_container); 329 } 330 if (!$cntnr.length) { 331 return false; 332 } 333 334 if (!options.slide_data_container) { 335 options.slide_data_container = data.settings.slide_data_container; 336 } 337 var slide_data_selectors = $.extend(true, {}, data.settings.slide_data_selectors); 338 if (options.slide_data_selectors) { 339 $.extend(true, slide_data_selectors, options.slide_data_selectors); 340 } 341 options.slide_data_selectors = slide_data_selectors; 342 343 var $self = $(this); 344 $cntnr.children(options.slide_data_container).each(function() { 345 var slide = RssPrivateMethods._findData($(this), options.slide_data_selectors); 346 $self.rsfSlideshow('addSlides', slide); 347 }); 348 }); 349 }, 350 351 352 353 354 355 356 357 358 /** 359 * Load and transition into the next slide 360 */ 361 362 nextSlide: function() { 363 return this.each(function() { 364 var data = $(this).data('rsf_slideshow'); 365 data.this_slide ++; 366 if (data.this_slide >= data.slides.length) { 367 if (data.settings.loop) { 368 data.this_slide = 0; 369 } 370 else { 371 data.this_slide = data.slides.length - 1; 372 $(this).rsfSlideshow('stopShow'); 373 return true; 374 } 375 } 376 $(this).rsfSlideshow('showSlide', data.slides[data.this_slide]); 377 }); 378 }, 379 380 381 /** 382 * Load and transition into the previous slide 383 */ 384 385 previousSlide: function() { 386 return this.each(function() { 387 var data = $(this).data('rsf_slideshow'); 388 data.this_slide --; 389 if (data.this_slide < 0) { 390 if (data.settings.loop) { 391 data.this_slide = data.slides.length - 1; 392 } 393 else { 394 data.this_slide = 0; 395 $(this).rsfSlideshow('stopShow'); 396 return true; 397 } 398 } 399 $(this).rsfSlideshow('showSlide', data.slides[data.this_slide]); 400 }); 401 }, 402 403 404 /** 405 * Load and transition into the slide with the provided key 406 * @params key (required) integer 407 * the array index of a slide object in the slides array 408 */ 409 410 goToSlide: function(key) { 411 return this.each(function() { 412 var data = $(this).data('rsf_slideshow'); 413 if (typeof data.slides[key] === 'object') { 414 data.this_slide = key; 415 $(this).rsfSlideshow('showSlide', data.slides[data.this_slide]); 416 } 417 }); 418 }, 419 420 421 /** 422 * Load and transition into the provided slide object 423 * @param slide (required) object 424 * a slide object (see docs) 425 */ 426 427 showSlide: function(slide) { 428 var $slideshow = this, 429 data = $slideshow.data('rsf_slideshow'), 430 containerWidth = $slideshow.width(), 431 containerHeight = $slideshow.height(); 432 RssPrivateMethods._trigger($slideshow, 'rsPreTransition'); 433 $slideshow.children('img:first').css('z-index', 0); 434 435 var whenLoaded = function(img) { 436 var $img = $(img); 437 $img.addClass('rsf-slideshow-image'); 438 var whenDimensions = function(width, height) { 439 RssPrivateMethods._trigger($slideshow, 'rsImageReady'); 440 var leftOffset = 0; 441 if (width) {
442 leftOffset = Math.ceil((containerWidth / 2) - (width / 2)); 443 } 444 var topOffset = 0; 445 if (height) { 446 topOffset = Math.ceil((containerHeight / 2) - (height / 2)); 447 } 448 $img.css({left: leftOffset}); 449 $img.css({top: topOffset}); 450 if (slide.image_title){ 451 $img.attr('title', slide.image_title); 452 } 453 if (slide.image_alt){ 454 $img.attr('alt', slide.image_alt); 455 } 456 if (slide.link_to) { 457 $img = $('<a href="' + slide.link_to + '"></a>').append($img); 458 } 459 var $slide = $('<div></div>'); 460 $slide.addClass(data.settings.slide_container_class); 461 $slide.append($img).css('display', 'none'); 462 if (slide.caption) { 463 var $capt = $('<div>' + slide.caption + '</div>'); 464 $capt.addClass(data.settings.slide_caption_class); 465 $capt.appendTo($slide); 466 if (slide.captionClass) { 467 $capt.addClass(slide.captionClass); 468 } 469 } 470 var effect = data.settings.effect; 471 if (slide.effect) { 472 effect = slide.effect; 473 } 474 RssPrivateMethods._trigger($slideshow, '_rsSlideReady', {$slide: $slide}); 475 RssPrivateMethods._trigger($slideshow, 'rsSlideReady', {$slide: $slide}); 476 RssPrivateMethods._transitionWith($slideshow, $slide, effect); 477 return true; 478 }; 479 RssPrivateMethods._getImageDimensions( 480 $slideshow, 481 $img, 482 whenDimensions, 483 (data.settings.interval * 1000) / 2, 484 function() {whenDimensions(); }); 485 }; 486 487 var newImg = new Image(); 488 $(newImg).bind('load', function() {whenLoaded(this); }); 489 newImg.src = slide.url; 490 491 return this; 492 }, 493 494 495 496 497 498 /***************************************************** 499 * Methods for adding slideshow control functionality 500 */ 501 502 503 /** 504 * Generate, place and bind a control for the slideshow 505 * @param type (required) string 506 * this must refer to a property of the control option (see options and docs) 507 */ 508 509 addControl: function(type) { 510 return this.each(function() { 511 var $slideshow = $(this), 512 settings = $slideshow.data('rsf_slideshow').settings; 513 var $control = settings.controls[type].generate($slideshow); 514 RssPrivateMethods._controlsContainer($slideshow); 515 settings.controls[type].place($slideshow, $control); 516 var bind_method = 'bind' + type.substr(0, 1).toUpperCase() + type.substr(1, type.length); 517 $slideshow.rsfSlideshow(bind_method, $control); 518 }); 519 }, 520 521 522 /* 523 * Play/ Pause toggle control 524 * @param $playPause (required) jQuery object 525 * elements to apply play/pause functionality to 526 */ 527 528 bindPlayPause: function($playPause) { 529 return this.each(function() { 530 var $slideshow = $(this); 531 var data = $slideshow.data('rsf_slideshow'); 532 $playPause.bind('click.rsfSlideshow', function(e) { 533 e.preventDefault(); 534 $slideshow.rsfSlideshow('toggleShow'); 535 }); 536 }); 537 }, 538 539 540 /** 541 * Previous slide control 542 * @param $prev (required) jQuery object 543 * elements to apply "previous slide" functionality to 544 * @param stop_show (optional) boolean 545 * if true, the slideshow is stopped when the control is clicked 546 * if not provided the global/options setting is used 547 */ 548 549 bindPreviousSlide: function($prev, autostop) { 550 return this.each(function() { 551 var $slideshow = $(this); 552 var data = $slideshow.data('rsf_slideshow'); 553 if (!autostop) { 554 autostop = data.settings.controls.previousSlide.autostop; 555 } 556 $prev.bind('click.rsfSlideshow', function(e) { 557 e.preventDefault(); 558 $slideshow.rsfSlideshow('previousSlide'); 559 if (autostop) { 560 $slideshow.rsfSlideshow('stopShow'); 561 } 562 }); 563 }); 564 }, 565 566 567 /** 568 * Next slide control 569 * $next (required) jQuery object 570 * elements to apply "next slide" functionality to 571 * @param stop_show (optional) boolean 572 * if true, the slideshow is stopped when the control is clicked 573 * if not provided the global/options setting is used 574 */ 575 576 bindNextSlide: function($next, autostop) { 577 return this.each(function() { 578 var $slideshow = $(this); 579 var data = $slideshow.data('rsf_slideshow'); 580 if (!autostop) { 581 autostop = data.settings.controls.nextSlide.autostop; 582 } 583 $next.bind('click.rsfSlideshow', function(e) { 584 e.preventDefault(); 585 $slideshow.rsfSlideshow('nextSlide'); 586 if (autostop) { 587 $slideshow.rsfSlideshow('stopShow'); 588 } 589 }); 590 }); 591 }, 592 593 594 /** 595 * Bind indexing functionality 596 */ 597 598 bindIndex: function($index, autostop) { 599 return this.each(function() { 600 var $slideshow = $(this), 601 settings = $slideshow.data('rsf_slideshow').settings; 602 if (!autostop) { 603 autostop = settings.controls.index.autostop; 604 } 605 var $indexLinks = settings.controls.index.getEach($slideshow); 606 $indexLinks.bind('click.rsfSlideshow', function(e) { 607 e.preventDefault(); 608 var slide_key = settings.controls.index.getSlideKey($(this)); 609 if (slide_key) { 610 $slideshow.rsfSlideshow('goToSlide', slide_key); 611 if (autostop) { 612 $slideshow.rsfSlideshow('stopShow'); 613 } 614 } 615 }); 616 RssPrivateMethods._bindActiveIndex($slideshow); 617 }); 618 } 619 620 621 }; 622 623 624 625 626 $.fn.rsfSlideshow = function(method) { 627 if (!this.length) { 628 return this; 629 } 630 // Method calling logic 631 if ( methods[method] ) { 632 return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); 633 } 634 else if ( typeof method === 'object' || ! method ) { 635 return methods.init.apply( this, arguments ); 636 } 637 else { 638 $.error( 'Method ' + method + ' does not exist on jQuery.rsfSlidehow' ); 639 } 640 }; 641 642 643 644 645 /** 646 * Private methods 647 */ 648 649 var RssPrivateMethods = { 650 651 /** 652 * Iterating through slide data selectors 653 * to find data for a single slide 654 * @param $slideData (required) jQuery object
655 * jQuery object containing the DOM element 656 * containing data for a single slide (with 657 * default settings this is a <li> element) 658 * @param slide_data_selectors (required) object 659 * information about where each slide property 660 * be found (see docs) 661 */ 662 663 _findData: function($slideData, slide_data_selectors) { 664 var slide = {}; 665 var slide_attr; 666 for (var key in slide_data_selectors) { 667 if (slide_data_selectors.hasOwnProperty(key)) { 668 var $slideDataClone = $slideData.clone(); 669 if (slide_data_selectors[key].selector) { 670 $slideDataClone = $slideDataClone.children(slide_data_selectors[key].selector); 671 } 672 if (slide_data_selectors[key].attr) { 673 slide_attr = $slideDataClone.attr(slide_data_selectors[key].attr); 674 } 675 else { 676 slide_attr = $slideDataClone.html(); 677 } 678 slide[key] = slide_attr; 679 } 680 } 681 return slide; 682 }, 683 684 685 /** 686 * Private method for adding a single slide object 687 * @param $slideshow (required) jQuery object 688 * the slideshow 689 * @param slide (required) string or object 690 * the URL of the slide image as a string or 691 * the slide data as a slide object (see docs) 692 * This should not be used directly, the public 693 * addSlides() method should be used instead. 694 */ 695 696 _addSlide: function($slideshow, slide) { 697 var data = $slideshow.data('rsf_slideshow'); 698 if (typeof slide === 'string') { 699 var url = $.trim(slide); 700 data.slides.push({url: url}); 701 } 702 else if (slide.url) { 703 for (var key in slide) { 704 if (slide.hasOwnProperty(key)) { 705 slide[key] = $.trim(slide[key]); 706 } 707 } 708 data.slides.push(slide); 709 } 710 }, 711 712 713 /** 714 * Remove a single slide from the slides array 715 * @param $slideshow (required) jQuery object 716 * the slideshow 717 */ 718 719 _removeSlide: function($slideshow, key) { 720 $slideshow.data('rsf_slideshow').slides.splice(key, 1); 721 }, 722 723 724 /** 725 * Perform a transition with a specified effect 726 * @param $slideshow (required) jQuery object 727 * the slideshow 728 * @param $slide (required) jQuery object 729 * the incoming slide container 730 * @param effect (required) string or object 731 * the transition effect name as a string or 732 * a transition effect object (see docs) 733 */ 734 735 _transitionWith: function($slideshow, $slide, effect) { 736 var data = $slideshow.data('rsf_slideshow'), 737 effect_iteration = 'random', 738 $prevSlide = $slideshow.find('.' + data.settings.slide_container_class + ':last'); 739 740 if ($prevSlide.length) { 741 $slide.insertAfter($prevSlide); 742 } 743 else { 744 $slide.prependTo($slideshow); 745 } 746 747 if (typeof effect === 'object' && effect.iteration && effect.effects) { 748 effect_iteration = effect.iteration; 749 effect = effect.effects; 750 } 751 752 if (effect instanceof Array) { 753 switch (effect_iteration) { 754 case 'loop': 755 data.effect_iterator.this_effect ++; 756 if (data.effect_iterator.this_effect > effect.length - 1) { 757 data.effect_iterator.this_effect = 0; 758 } 759 break; 760 case 'backAndForth': 761 data.effect_iterator.this_effect += data.effect_iterator.direction; 762 if (data.effect_iterator.this_effect < 0) { 763 data.effect_iterator.this_effect = 1; 764 data.effect_iterator.direction = data.effect_iterator.direction * -1; 765 } 766 if (data.effect_iterator.this_effect > effect.length - 1) { 767 data.effect_iterator.this_effect = effect.length - 2; 768 data.effect_iterator.direction = data.effect_iterator.direction * -1; 769 } 770 break; 771 default: 772 data.effect_iterator.this_effect = Math.floor(Math.random() * effect.length); 773 break; 774 } 775 effect = effect[data.effect_iterator.this_effect]; 776 } 777 778 if ($.rsfSlideshow.transitions[effect] && 779 typeof($.rsfSlideshow.transitions[effect]) === 'function') { 780 $.rsfSlideshow.transitions[effect]($slideshow, $slide); 781 } 782 }, 783 784 785 /** 786 * Perform slide animation 787 * @param $slideshow (required) jQuery object 788 * the slideshow 789 * @param $slide (required) jQuery object 790 * the incoming slide container 791 * @param $previousSlide (required) jQuery object 792 * the outgoing slide container 793 * @param left_offset (required) integer 794 * the left start position of the incoming slide in pixels 795 * @param left_offset (required) integer 796 * the top start position of the incoming slide in pixels 797 */ 798 799 _doSlide: function($slideshow, $slide, left_offset, top_offset) { 800 var data = $slideshow.data('rsf_slideshow'), 801 $prevSlide = $slide.prev(); 802 $slide.css({top: top_offset, left: left_offset}); 803 $slide.css('display', 'block'); 804 805 $slide.stop().animate( 806 {top: 0, left: 0}, 807 data.settings.transition, 808 data.settings.easing, 809 function() { 810 RssPrivateMethods._endTransition($slideshow, $slide); 811 } 812 ); 813 814 $prevSlide.stop().animate( 815 {top: (0 - top_offset), left: (0 - left_offset)}, 816 data.settings.transition, 817 data.settings.easing 818 ); 819 }, 820 821 822 /** 823 * Handles finding the image dimensions 824 * @param $slideshow (required) jQuery object 825 * the slideshow 826 * @param $img (required) jQuery object 827 * the loaded image 828 * @param success (required) function 829 * function to call when dimensions are found 830 * @param timeout (optional) integer 831 * the time after which the method will stop trying 832 * to find the image dimensions 833 * @param onTimeout (required) function 834 * function to call when timeout is reached 835 */ 836 837 _getImageDimensions: function($slideshow, $img, sucesss, timeout, onT
837imeout, time) { 838 if (!time) { 839 time = 0; 840 $slideshow.prepend($img); 841 } 842 var width = $img.outerWidth(); 843 var height = $img.outerHeight(); 844 if (width && height) { 845 $img.detach(); 846 sucesss(width, height); 847 return true; 848 } 849 if (timeout && time > timeout) { 850 $img.detach(); 851 if (onTimeout && typeof(onTimeout) === 'function') { 852 onTimeout(timeout, time); 853 } 854 return false; 855 } 856 time += 200; 857 setTimeout(function() { 858 RssPrivateMethods._getImageDimensions($slideshow, $img, sucesss, timeout, onTimeout, time); 859 }, 200); 860 }, 861 862 /** 863 * Anything that needs to be done after a transition ends 864 * @param $slideshow (required) jQuery object 865 * the slideshow 866 */ 867 868 _endTransition: function($slideshow, $slide) { 869 $slide.prev().remove(); 870 RssPrivateMethods._trigger($slideshow, 'rsPostTransition'); 871 if ($slideshow.rsfSlideshow('currentSlideKey') === $slideshow.rsfSlideshow('totalSlides') - 1) { 872 RssPrivateMethods._trigger($slideshow, 'rsLastSlide'); 873 } 874 else if ($slideshow.rsfSlideshow('currentSlideKey') === 0) { 875 RssPrivateMethods._trigger($slideshow, 'rsFirstSlide'); 876 } 877 }, 878 879 880 /** 881 * Bind event handlers for adding and remving a class to index elements 882 * according to the current slide key 883 * @param $slideshow (required) jQuery object 884 * the slideshow 885 */ 886 887 _bindActiveIndex: function($slideshow) { 888 var indexSettings = $slideshow.data('rsf_slideshow').settings.controls.index; 889 $slideshow.bind('rsPreTransition', function() { 890 var current_slide_key = $(this).rsfSlideshow('currentSlideKey'); 891 indexSettings.getEach($slideshow).removeClass(indexSettings.active_class); 892 indexSettings.getSingleByKey($slideshow, current_slide_key).addClass(indexSettings.active_class); 893 }); 894 }, 895 896 897 /**
898 * check for controls container and generate if not present 899 * @param $slideshow (required) jQuery object 900 * the slideshow 901 */ 902 903 _controlsContainer: function($slideshow) { 904 var settings = $slideshow.data('rsf_slideshow').settings; 905 if (!settings.controls.container.get($slideshow).length) { 906 var $container = settings.controls.container.generate($slideshow); 907 settings.controls.container.place($slideshow, $container); 908 } 909 }, 910 911 912 /** 913 * Wrapper for triggering slideshow events 914 * @param $slideshow (required) jQuery object 915 * the slideshow 916 * @param e (required) string 917 * the custom event name 918 * @param event_data (optional) object 919 * addional data to pass to event handlers 920 */ 921 922 _trigger: function($slideshow, e, event_data) { 923 var data = $slideshow.data('rsf_slideshow'); 924 if (typeof event_data !== 'object') { 925 event_data = {}; 926 } 927 $.extend(event_data, {slide_key: data.this_slide, slide: data.slides[data.this_slide]}); 928 $slideshow.trigger(e, event_data); 929 }, 930 931 932 /** 933 * Set the timer for the next slide 934 */ 935 936 _setTimeout: function($slideshow, interval) { 937 var data = $slideshow.data('rsf_slideshow'); 938 if (data.interval_id) { 939 clearTimeout(data.interval_id); 940 } 941 if (!interval) { 942 interval = data.settings.interval; 943 } 944 if (interval <= data.settings.transition / 1000) { 945 interval = (data.settings.transition / 1000) + 0.1; 946 } 947 data.interval_id = setTimeout(function() { 948 $slideshow.rsfSlideshow('nextSlide'); 949 }, interval * 1000); 950 } 951 952 }; 953 954 955 956 /** 957 * Default options 958 * Any default options can be set directly by accessing 959 * the $.rsfSlideshow.defaults hash 960 */ 961 962 $.rsfSlideshow = { 963 defaults: { 964 // Duration of the interval between each slide in seconds 965 interval: 5, 966 // Duration of the transition effect in milliseconds 967 transition: 1000, 968 // The transition effect. 969 effect: 'fade', 970 // Easing for slide effects (use the easing jQuery plugin for more options) 971 easing: 'swing', 972 // If true, the slideshow will loop 973 loop: true, 974 // Start slideshow automatically on initialisation 975 autostart: true, 976 // Slides to add to the slideshow 977 slides: [], 978 // Class of the div containing the slide image and caption 979 slide_container_class: 'slide-container', 980 // Class to add to slide caption <span> 981 slide_caption_class: 'slide-caption', 982 // jQuery selector for the element containing slide data when using markup to pass data. 983 // If this is an ID (starts with '#') the element can be placed anywhere on the page, 984 // Any other selector is assumed to be a child of the slideshow element. 985 data_container: 'ol.slides', 986 // jQuery selector for each slide data element 987 slide_data_container: 'li', 988 // Objects containing selection routes for slide attributes 989 // One or both of 'selector' and/or 'attr' must be present 990 slide_data_selectors: { 991 url: {selector: 'a', attr: 'href'}, 992 caption: {selector: 'a', attr: 'title'}, 993 link_to: {selector: 'a', attr: 'data-link-to'}, 994 effect: {selector: 'a', attr: 'data-effect'} 995 }, 996 997 998 // Default event handlers, assigned to every instance of the slideshow 999 eventHandlers: { 1000 rsStartShow: function(rssObj, e) { 1001 var controlSettings = $(rssObj).data('rsf_slideshow').settings.controls.playPause; 1002 var $playPause = controlSettings.get($(rssObj)); 1003 $playPause.html('Pause').addClass(controlSettings.playing_class); 1004 }, 1005 rsStopShow: function(rssObj, e) { 1006 var controlSettings = $(rssObj).data('rsf_slideshow').settings.controls.playPause; 1007 var $playPause = controlSettings.get($(rssObj)); 1008 $playPause.html('Play').addClass(controlSettings.paused_class); 1009 } 1010 }, 1011 1012 1013 /** 1014 * These options define methods for generating, placing and finding 1015 * slideshow control elements. 1016 */ 1017 1018 controls: { 1019 playPause: { 1020 generate: function($slideshow) { 1021 return $('<a href="#" class="rs-play-pause ' + 1022 $slideshow.data('rsf_slideshow').settings.controls.playPause.paused_class + 1023 '" data-control-for="' + 1024 $slideshow.attr('id') + '">Play</a>'); 1025 }, 1026 place: function($slideshow, $control) { 1027 var $container = 1028 $slideshow.data('rsf_slideshow').settings.controls.container.get($slideshow); 1029 $container.append($control); 1030 }, 1031 get: function($slideshow) { 1032 return $('.rs-play-pause[data-control-for="' + $slideshow.attr('id') + '"]'); 1033 }, 1034 playing_class: 'rs-playing', 1035 paused_class: 'rs-paused',
1036 auto: false 1037 }, 1038 previousSlide: { 1039 generate: function($slideshow) { 1040 return $('<a href="#" class="rs-prev" data-control-for="' + 1041 $slideshow.attr('id') + '"><</a>'); 1042 }, 1043 place: function($slideshow, $control) { 1044 var $container = 1045 $slideshow.data('rsf_slideshow').settings.controls.container.get($slideshow); 1046 $container.append($control); 1047 }, 1048 get: function($slideshow) { 1049 return $('.rs-prev[data-control-for="' + $slideshow.attr('id') + '"]'); 1050 }, 1051 autostop: true, 1052 auto: false 1053 }, 1054 nextSlide: { 1055 generate: function($slideshow) { 1056 return $('<a href="#" class="rs-next" data-control-for="' + 1057 $slideshow.attr('id') + '">></a>'); 1058 }, 1059 place: function($slideshow, $control) { 1060 var $container = 1061 $slideshow.data('rsf_slideshow').settings.controls.container.get($slideshow); 1062 $container.append($control); 1063 }, 1064 get: function($slideshow) { 1065 return $('.rs-next[data-control-for="' + $slideshow.attr('id') + '"]'); 1066 }, 1067 autostop: true, 1068 auto: false 1069 }, 1070 index: { 1071 generate: function($slideshow) { 1072 var slide_count = $slideshow.rsfSlideshow('totalSlides'), 1073 $indexControl = $('<ul class="rs-index-list clearfix"></ul>'); 1074 $indexControl.attr('data-control-for', $slideshow.attr('id')); 1075 for (var i = 0; i < slide_count; i ++) { 1076 var $link = $('<a href="#"></a>'); 1077 $link.addClass('rs-index'); 1078 $link.attr('data-control-for', $slideshow.attr('id')); 1079 $link.attr('data-slide-key', i); 1080 $link.append(i + 1); 1081 if (i === $slideshow.rsfSlideshow('currentSlideKey')) { 1082 $link.addClass('rs-active'); 1083 } 1084 var $li = $('<li></li>'); 1085 $li.append($link); 1086 $indexControl.append($li); 1087 } 1088 return $indexControl; 1089 }, 1090 place: function($slideshow, $control) { 1091 var $container = 1092 $slideshow.data('rsf_slideshow').settings.controls.container.get($slideshow); 1093 $container.append($control); 1094 }, 1095 get: function($slideshow) { 1096 return $('.rs-index-list[data-control-for="' + $slideshow.attr('id') + '"]'); 1097 }, 1098 getEach: function($slideshow) { 1099 return $('.rs-index[data-control-for="' + $slideshow.attr('id') + '"]'); 1100 }, 1101 getSingleByKey: function($slideshow, slide_key) { 1102 return $('.rs-index[data-control-for="' + 1103 $slideshow.attr('id') + '"][data-slide-key="' + slide_key + '"]'); 1104 }, 1105 getSlideKey: function($controlItem) { 1106 return $controlItem.attr('data-slide-key'); 1107 }, 1108 active_class: 'rs-active', 1109 autostop: true, 1110 auto: false 1111 }, 1112 container: { 1113 generate: function($slideshow) { 1114 return $('<div class="rs-controls clearfix" id="rs-controls-' + $slideshow.attr('id') + '"></div>'); 1115 }, 1116 place: function($slideshow, $control) { 1117 $slideshow.after($control); 1118 }, 1119 get: function($slideshow) { 1120 return $('#rs-controls-' + $slideshow.attr('id')); 1121 } 1122 } 1123 } 1124 }, 1125 1126 1127 // Transition effects 1128 transitions: { 1129 none: function($slideshow, $slide) { 1130 $slide.css('display', 'block'); 1131 }, 1132 fade: function($slideshow, $slide) { 1133 $slide.fadeIn( 1134 $slideshow.data('rsf_slideshow').settings.transition, 1135 function() { 1136 RssPrivateMethods._endTransition($slideshow, $slide); 1137 }); 1138 }, 1139 slideLeft: function($slideshow, $slide) { 1140 var left_offset = $slide.outerWidth(); 1141 RssPrivateMethods._doSlide($slideshow, $slide, left_offset, 0); 1142 }, 1143 slideRight: function($slideshow, $slide) { 1144 var left_offset = 0 - $slide.outerWidth(); 1145 RssPrivateMethods._doSlide($slideshow, $slide, left_offset, 0); 1146 }, 1147 slideUp: function($slideshow, $slide) { 1148 var top_offset = $slide.outerHeight(); 1149 RssPrivateMethods._doSlide($slideshow, $slide, 0, top_offset); 1150 }, 1151 slideDown: function($slideshow, $slide) { 1152 var top_offset = 0 - $slide.outerHeight(); 1153 RssPrivateMethods._doSlide($slideshow, $slide, 0, top_offset); 1154 } 1155 } 1156 1157 }; 1158 1159 1160})( jQuery ); 1161
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.