1/** 2 * jquery.elastislide.js v1.1.0 3 * http://www.codrops.com 4 * 5 * Licensed under the MIT license. 6 * http://www.opensource.org/licenses/mit-license.php 7 * 8 * Copyright 2012, Codrops 9 * http://www.codrops.com 10 */ 11 12;( function( $, window, undefined ) { 13 14 'use strict'; 15 16 /* 17 * debouncedresize: special jQuery event that happens once after a window resize 18 * 19 * latest version and complete README available on Github: 20 * https://github.com/louisremi/jquery-smartresize/blob/master/jquery.debouncedresize.js 21 * 22 * Copyright 2011 @louis_remi 23 * Licensed under the MIT license. 24 */ 25 var $event = $.event, 26 $special, 27 resizeTimeout; 28 29 $special = $event.special.debouncedresize = { 30 setup: function() { 31 $( this ).on( "resize", $special.handler ); 32 }, 33 teardown: function() { 34 $( this ).off( "resize", $special.handler ); 35 }, 36 handler: function( event, execAsap ) { 37 // Save the context 38 var context = this, 39 args = arguments, 40 dispatch = function() { 41 // set correct event type 42 event.type = "debouncedresize"; 43 $event.dispatch.apply( context, args ); 44 }; 45 46 if ( resizeTimeout ) { 47 clearTimeout( resizeTimeout ); 48 } 49 50 execAsap ? 51 dispatch() : 52 resizeTimeout = setTimeout( dispatch, $special.threshold ); 53 }, 54 threshold: 150 55 }; 56 57 // ======================= imagesLoaded Plugin =============================== 58 // https://github.com/desandro/imagesloaded 59 60 // $('#my-container').imagesLoaded(myFunction) 61 // execute a callback when all images have loaded. 62 // needed because .load() doesn't work on cached images 63 64 // callback function gets image collection as argument 65 // this is the container 66 67 // original: mit license. paul irish. 2010. 68 // contributors: Oren Solomianik, David DeSandro, Yiannis Chatzikonstantinou 69 70 // blank image data-uri bypasses webkit log warning (thx doug jones) 71 var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=='; 72 73 $.fn.imagesLoaded = function( callback ) { 74 var $this = this, 75 deferred = $.isFunction($.Deferred) ? $.Deferred() : 0, 76 hasNotify = $.isFunction(deferred.notify), 77 $images = $this.find('img').add( $this.filter('img') ), 78 loaded = [], 79 proper = [], 80 broken = []; 81 82 // Register deferred callbacks 83 if ($.isPlainObject(callback)) { 84 $.each(callback, function (key, value) { 85 if (key === 'callback') { 86 callback = value; 87 } else if (deferred) { 88 deferred[key](value); 89 } 90 }); 91 } 92 93 function doneLoading() { 94 var $proper = $(proper), 95 $broken = $(broken); 96 97 if ( deferred ) { 98 if ( broken.length ) { 99 deferred.reject( $images, $proper, $broken ); 100 } else { 101 deferred.resolve( $images ); 102 } 103 } 104 105 if ( $.isFunction( callback ) ) { 106 callback.call( $this, $images, $proper, $broken ); 107 } 108 109 } 110 111 function imgLoaded( img, isBroken ) { 112 // don't proceed if BLANK image, or image is already loaded 113 if ( img.src === BLANK || $.inArray( img, loaded ) !== -1 ) { 114 return; 115 } 116 117 // store element in loaded images array 118 loaded.push( img ); 119 120 // keep track of broken and properly loaded images 121 if ( isBroken ) { 122 broken.push( img ); 123 } else { 124 proper.push( img ); 125 } 126 127 // cache image and its state for future calls 128 $.data( img, 'imagesLoaded', { isBroken: isBroken, src: img.src } ); 129 130 // trigger deferred progress method if present 131 if ( hasNotify ) { 132 deferred.notifyWith( $(img), [ isBroken, $images, $(proper), $(broken) ] ); 133 } 134 135 // call doneLoading and clean listeners if all images are loaded 136 if ( $images.length === loaded.length ){ 137 setTimeout( doneLoading ); 138 $images.unbind( '.imagesLoaded' ); 139 } 140 } 141 142 // if no images, trigger immediately 143 if ( !$images.length ) { 144 doneLoading(); 145 } else { 146 $images.bind( 'load.imagesLoaded error.imagesLoaded', function( event ){ 147 // trigger imgLoaded 148 imgLoaded( event.target, event.type === 'error' ); 149 }).each( function( i, el ) { 150 var src = el.src; 151 152 // find out if this image has been already checked for status 153 // if it was, and src has not changed, call imgLoaded on it 154 var cached = $.data( el, 'imagesLoaded' ); 155 if ( cached && cached.src === src ) { 156 imgLoaded( el, cached.isBroken ); 157 return; 158 } 159 160 // if complete is true and browser supports natural sizes, try 161 // to check for image status manually
162 if ( el.complete && el.naturalWidth !== undefined ) { 163 imgLoaded( el, el.naturalWidth === 0 || el.naturalHeight === 0 ); 164 return; 165 } 166 167 // cached images don't fire load sometimes, so we reset src, but only when 168 // dealing with IE, or image is complete (loaded) and failed manual check 169 // webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f 170 if ( el.readyState || el.complete ) { 171 el.src = BLANK; 172 el.src = src; 173 } 174 }); 175 } 176 177 return deferred ? deferred.promise( $this ) : $this; 178 }; 179 180 // global 181 var $window = $( window ), 182 Modernizr = window.Modernizr; 183 184 $.Elastislide = function( options, element ) { 185 186 this.$el = $( element ); 187 this._init( options ); 188 189 }; 190 191 $.Elastislide.defaults = { 192 // orientation 'horizontal' || 'vertical' 193 orientation : 'horizontal', 194 // sliding speed 195 speed : 300, 196 // sliding easing 197 easing : 'ease-in-out', 198 // the minimum number of items to show. 199 // when we resize the window, this will make sure minItems are always shown 200 // (unless of course minItems is higher than the total number of elements) 201 minItems : 3, 202 // index of the current item (left most item of the carousel) 203 start : 0, 204 // autoslide feature: true || false 205 // automatically loops through the carousel (after hitting the end of the list goes back to front) 206 // disabled by default 207 autoSlide: false, 208 // autoslide delay time, specifies time interval between autoslide steps (in milliseconds) 209 // 3000ms by default 210 delayTime: 3000, 211 // click item callback 212 onClick : function( el, position, evt ) { return false; }, 213 onReady : function() { return false; }, 214 onBeforeSlide : function() { return false; }, 215 onAfterSlide : function() { return false; } 216 }; 217 218 $.Elastislide.prototype = { 219 220 _init : function( options ) { 221 // options 222 this.options = $.extend( true, {}, $.Elastislide.defaults, options ); 223 224 // https://github.com/twitter/bootstrap/issues/2870 225 var self = this, 226 transEndEventNames = { 227 'WebkitTransition' : 'webkitTransitionEnd', 228 'MozTransition' : 'transitionend', 229 'OTransition' : 'oTransitionEnd', 230 'msTransition' : 'MSTransitionEnd', 231 'transition' : 'transitionend' 232 }; 233 234 this.transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ]; 235 236 // suport for css transforms and css transitions 237 this.support = Modernizr.csstransitions && Modernizr.csstransforms; 238 239 // current item's index 240 this.current = this.options.start; 241 242 // control if it's sliding 243 this.isSliding = false; 244 245 this.$items = this.$el.children( 'li' ); 246 // total number of items 247 this.itemsCount = this.$items.length; 248 if( this.itemsCount === 0 ) { 249 250 return false; 251 252 } 253 254 255 if (this.options.orientation === 'horizontal') 256 { 257 var containerw = this.$el.parent().width(); 258 var tmpItemWidth = parseInt(this.options.width) + parseInt(this.options.space); 259 var tmpMinItems = Math.floor(containerw/tmpItemWidth); 260 this.options.minItems = tmpMinItems; 261 } 262 263 this._validate(); 264 // remove white space 265 this.$items.detach(); 266 this.$el.empty(); 267 this.$el.append( this.$items ); 268 269 // main wrapper 270 this.$el.wrap( '<div class="elastislide-wrapper elastislide-loading elastislide-' + this.options.orientation + '"></div>' ); 271 272 // check if we applied a transition to the <ul> 273 this.hasTransition = false; 274 275 // add transition for the <ul> 276 this.hasTransitionTimeout = setTimeout( function() { 277 278 self._addTransition(); 279 280 }, 100 ); 281 282 // preload the images 283 284 this.$el.imagesLoaded( function() { 285 286 self.$el.show(); 287 288 self._layout(); 289 self._configure(); 290 291 if( self.hasTransition ) { 292 293 // slide to current's position 294 self._removeTransition(); 295 self._slideToItem( self.current ); 296 297 self.$el.on( self.transEndEventName, function() { 298 299 self.$el.off( self.transEndEventName ); 300 self._setWrapperSize(); 301 // add transition for the <ul> 302 self._addTransition(); 303 self._initEvents(); 304 305 } ); 306 307 } 308 else { 309 310 clearTimeout( self.hasTransitionTimeout ); 311 self._setWrapperSize(); 312 self._initEvents(); 313 // slide to current's position 314 self._slideToItem( self.current ); 315 setTimeout( function() { self._addTransition(); }, 25 ); 316 317 } 318 319 self.options.onReady(); 320 321 } ); 322 323 },
324 _validate : function() { 325 326 if( this.options.speed < 0 ) { 327 328 this.options.speed = 500; 329 330 } 331 332 if( this.options.minItems < 1 || this.options.minItems > this.itemsCount ) { 333 334 this.options.minItems = 1; 335 336 } 337 if( this.options.start < 0 || this.options.start > this.itemsCount - 1 ) { 338 339 this.options.start = 0; 340 341 } 342 if( this.options.orientation != 'horizontal' && this.options.orientation != 'vertical' ) { 343 344 this.options.orientation = 'horizontal'; 345 346 } 347 348 }, 349 _layout : function() { 350 351 if (this.options.container_side_fade !== 'none') 352 { 353 this.$el.wrap( '<div class="elastislide-carousel fade-' + this.options.container_side_fade + '"></div>' ); 354 } 355 else 356 { 357 this.$el.wrap( '<div class="elastislide-carousel"></div>' ); 358 } 359 360 this.$carousel = this.$el.parent(); 361 362 if (this.options.container_side_fade !== 'none') 363 { 364 365 $('<div class="elastislide-carousel-inner1"></div>').appendTo( this.$carousel ); 366 $('<div class="elastislide-carousel-inner2"></div>').appendTo( this.$carousel ); 367 } 368 369 this.$wrapper = this.$carousel.parent().removeClass( 'elastislide-loading' ); 370 371 // save original image sizes 372 var $img = this.$items.find( 'img:first' ); 373 374 this.imgSize = { width : parseInt(this.options.width), height : parseInt(this.options.height)}; 375 376 this._setItemsSize(); 377 if (this.options.orientation === 'horizontal') 378 { 379 this.$el.css( 'max-height', this.imgSize.height); 380 } 381 else 382 { 383 if (this.options.minItems >= 2) 384 { 385 this.$el.css( 'height', this.options.minItems * this.imgSize.height + this.options.minItems*parseInt(this.options.space) - this.options.image_shadow); 386 } 387 else 388 { 389 this.$el.css( 'height', this.options.minItems * this.imgSize.height ); 390 } 391 } 392 // add the controls 393 this._addControls(); 394 395 }, 396 _addTransition : function() { 397 398 if( this.support ) { 399 400 this.$el.css( 'transition', 'all ' + this.options.speed + 'ms ' + this.options.easing ); 401 402 } 403 this.hasTransition = true; 404 405 }, 406 _removeTransition : function() { 407 408 if( this.support ) { 409 410 this.$el.css( 'transition', 'all 0s' ); 411 412 } 413 this.hasTransition = false; 414 415 }, 416 _addControls : function() { 417 418 var self = this; 419 420 // add navigation elements 421 this.$navigation = $( '<nav><span class="elastislide-prev">Previous</span><span class="elastislide-next">Next</span></nav>' ) 422 .appendTo( this.$wrapper ); 423 424 425 this.$navPrev = this.$navigation.find( 'span.elastislide-prev' ).on( 'mousedown.elastislide', function( event ) { 426 427 self._slide( 'prev' ); 428 return false; 429 430 } ); 431 432 this.$navNext = this.$navigation.find( 'span.elastislide-next' ).on( 'mousedown.elastislide', function( event ) { 433 434 self._slide( 'next' ); 435 return false; 436 437 } ); 438 439 }, 440 _setItemsSize : function() { 441 442 // width for the items (%) 443 var w = this.options.orientation === 'horizontal' ? ( 100 / 2 ) : 100; 444 //var w = 100 / 3; 445 if (this.options.orientation === 'horizontal') 446 { 447 this.$items.css( { 448 'width' : w + '%', 449 'max-width' : (parseInt(this.imgSize.width) + parseInt(this.options.space)), 450 'max-height' : this.imgSize.height 451 } ); 452 } 453 else 454 { 455 this.$items.css( { 456 'width' : w + '%', 457 'max-width' : this.imgSize.width, 458 'max-height' : (parseInt(this.imgSize.height) + parseInt(this.options.space)) 459 } ); 460 } 461 462 if( this.options.orientation === 'vertical' ) { 463 this.$wrapper.css( 'max-width', this.imgSize.width + parseInt( this.$wrapper.css( 'padding-left' ) ) + parseInt( this.$wrapper.css( 'padding-right' ) ) + 2*this.options.image_shadow + 2*this.options.container_border); 464 } 465 466 }, 467 _setWrapperSize : function() { 468 469 if( this.options.orientation === 'vertical' ) { 470 if (this.options.minItems >=2) 471 { 472 this.$wrapper.css( { 473 'height' : this.options.minItems * this.imgSize.height + parseInt( this.$wrapper.css( 'padding-top' ) ) + parseInt( this.$wrapper.css( 'padding-bottom' ) ) + this.options.minItems*parseInt(this.options.space) + 2*this.options.container_border 474 } ); 475 } 476 else 477 { 478 this.$wrapper.css( { 479 'height' : this.options.minItems * this.imgSize.height + parseInt( this.$wrapper.css( 'padding-top' ) ) + parseInt( this.$wrapper.css( 'padding-bottom' ) ) + 2*this.options.container_border 480 } ); 481 } 482 483 484 } 485 486 }, 487 _configure : function() { 488 489 // check how many items fit in the carousel (visible area -> this.$carousel.width() ) 490 491 /* 492 this.fitCount = this.options.orientation === 'horizontal' ? 493 this.$carousel.width() < this.options.minItems * this.imgSize.width ? this.options.minItems : Math.floor( this.$carousel.width() / this.imgSize.width ) : 494 this.$carousel.height() < this.options.minItems * this.imgSize.height ? this.options.minItems : Math.floor( this.$carousel.height() / this.imgSize.height ); 495 */ 496 497 this.fitCount = this.options.orientation === 'horizontal' ? 498 this.options.minItems : 499 this.options.minItems; 500 }, 501 _initEvents : function() { 502 503 var self = this; 504 505 //autoslide. To enablethis, set "var autoSlide" to "true" above. 506 if( this.options.autoSlide ) { 507 var translation = 0; 508 // width/height of an item ( <li> ) 509 var itemSpace = this.options.orientation === 'horizontal' ? this.$items.outerWidth( true ) : this.$items.outerHeight( true ); 510 // total width/height of the <ul> 511 var totalSpace = this.itemsCount * itemSpace; 512 // visible width/height 513 var visibleSpace = this.options.orientation === 'horizontal' ? this.$carousel.width() : this.$carousel.height(); 514 window.setInterval(function(){ 515 //test if we should go to next slide or return to first slide 516 if(totalSpace > translation + visibleSpace) 517 { 518 self._slide('next'); 519 translation += visibleSpace; 520 } 521 else 522 { 523 self._slideTo(0); 524 translation = 0; 525 } 526 }, this.options.delayTime); 527 } 528 529 $window.on( 'debouncedresize.elastislide', function() { 530 531 /*if (self.options.orientation === 'horizontal') 532 { 533 var containerw = self.$el.parent().width(); 534 var tmpMinItems = Math.floor(containerw/self.options.width); 535 self.options.minItems = tmpMinItems; 536 }*/ 537 538 self._setItemsSize(); 539 self._configure(); 540 self._slideToItem( self.current ); 541 542 } ); 543 544 this.$el.on( this.transEndEventName, function() { 545 546 self._onEndTransition(); 547 548 } ); 549 550 if( this.options.orientation === 'horizontal' ) { 551 552 this.$el.on( { 553 swipeleft : function() { 554 555 self._slide( 'next' ); 556 557 }, 558 swiperight : function() { 559 560 self._slide( 'prev' ); 561 562 } 563 } ); 564 565 } 566 else { 567 568 this.$el.on( { 569 swipeup : function() { 570 571 self._slide( 'next' ); 572 573 }, 574 swipedown : function() { 575 576 self._slide( 'prev' ); 577 578 } 579 } ); 580 581 } 582 583 // item click event 584 this.$el.on( 'click.elastislide', 'li', function( event ) { 585 586 var $item = $( this ); 587 588 self.options.onClick( $item, $item.index(), event ); 589 590 }); 591 592 }, 593 _destroy : function( callback ) { 594 595 this.$el.off( this.transEndEventName ).off( 'swipeleft swiperight swipeup swipedown .elastislide' ); 596 $window.off( '.elastislide' ); 597 598 this.$el.css( { 599 'max-height' : 'none', 600 'transition' : 'none' 601 } ).unwrap( this.$carousel ).unwrap( this.$wrapper ); 602 603 this.$items.css( { 604 'width' : 'auto', 605 'max-width' : 'none', 606 'max-height' : 'none' 607 } ); 608 609 this.$navigation.remove(); 610 this.$wrapper.remove(); 611 612 if( callback ) { 613 614 callback.call(); 615 616 } 617 618 }, 619 _toggleControls : function( dir, display ) { 620
621 if( display ) { 622 623 ( dir === 'next' ) ? this.$navNext.show() : this.$navPrev.show(); 624 625 } 626 else { 627 628 ( dir === 'next' ) ? this.$navNext.hide() : this.$navPrev.hide(); 629 630 } 631 632 }, 633 _slide : function( dir, tvalue ) { 634 635 if( this.isSliding ) { 636 637 return false; 638 639 } 640 641 this.options.onBeforeSlide(); 642 643 this.isSliding = true; 644 645 var self = this, 646 translation = this.translation || 0, 647 // width/height of an item ( <li> ) 648 itemSpace = this.options.orientation === 'horizontal' ? this.$items.outerWidth( true ) : this.$items.outerHeight( true ), 649 // total width/height of the <ul> 650 totalSpace = this.itemsCount * itemSpace, 651 // visible width/height 652 visibleSpace = this.options.orientation === 'horizontal' ? this.$carousel.width() - 2*this.options.image_shadow: this.$carousel.height() + parseInt(this.options.space) - 2*this.options.image_shadow; 653 654 if( tvalue === undefined ) { 655 656 var amount = this.fitCount * itemSpace; 657 658 if( amount < 0 ) { 659 660 return false; 661 662 } 663 664 if( dir === 'next' && totalSpace - ( Math.abs( translation ) + amount ) < visibleSpace ) { 665 666 amount = totalSpace - ( Math.abs( translation ) + visibleSpace ); 667 668 // show / hide navigation buttons 669 this._toggleControls( 'next', false ); 670 this._toggleControls( 'prev', true ); 671 672 } 673 else if( dir === 'prev' && Math.abs( translation ) - amount < 0 ) { 674 675 amount = Math.abs( translation ); 676 677 // show / hide navigation buttons 678 this._toggleControls( 'next', true ); 679 this._toggleControls( 'prev', false ); 680 681 } 682 else { 683 684 // future translation value 685 var ftv = dir === 'next' ? Math.abs( translation ) + Math.abs( amount ) : Math.abs( translation ) - Math.abs( amount ); 686 687 // show / hide navigation buttons 688 ftv > 0 ? this._toggleControls( 'prev', true ) : this._toggleControls( 'prev', false ); 689 ftv < totalSpace - visibleSpace ? this._toggleControls( 'next', true ) : this._toggleControls( 'next', false ); 690 691 } 692 693 tvalue = dir === 'next' ? translation - amount : translation + amount; 694 } 695 else { 696 697 var amount = Math.abs( tvalue ); 698 699 if( Math.max( totalSpace, visibleSpace ) - amount < visibleSpace ) { 700 701 tvalue = - ( Math.max( totalSpace, visibleSpace ) - visibleSpace ); 702 703 } 704 705 // show / hide navigation buttons 706 amount > 0 ? this._toggleControls( 'prev', true ) : this._toggleControls( 'prev', false ); 707 Math.max( totalSpace, visibleSpace ) - visibleSpace > amount ? this._toggleControls( 'next', true ) : this._toggleControls( 'next', false ); 708 709 } 710 711 this.translation = tvalue; 712 713 if( translation === tvalue ) { 714 715 this._onEndTransition(); 716 return false; 717 718 } 719 720 if( this.support ) { 721 722 this.options.orientation === 'horizontal' ? this.$el.css( 'transform', 'translateX(' + tvalue + 'px)' ) : this.$el.css( 'transform', 'translateY(' + tvalue + 'px)' ); 723 724 } 725 else { 726 727 $.fn.applyStyle = this.hasTransition ? $.fn.animate : $.fn.css; 728 var styleCSS = this.options.orientation === 'horizontal' ? { left : tvalue } : { top : tvalue }; 729 730 this.$el.stop().applyStyle( styleCSS, $.extend( true, [], { duration : this.options.speed, complete : function() { 731 732 self._onEndTransition(); 733 734 } } ) ); 735 736 } 737 738 if( !this.hasTransition ) { 739 740 this._onEndTransition(); 741 742 } 743 744 }, 745 _onEndTransition : function() { 746 747 this.isSliding = false; 748 this.options.onAfterSlide(); 749 750 }, 751 _slideTo : function( pos ) { 752 753 var pos = pos || this.current, 754 translation = Math.abs( this.translation ) || 0, 755 itemSpace = this.options.orientation === 'horizontal' ? this.$items.outerWidth( true ) : this.$items.outerHeight( true ), 756 posR = translation + this.$carousel.width(), 757 ftv = Math.abs( pos * itemSpace ); 758 759 if( ftv + itemSpace > posR || ftv < translation ) { 760 761 this._slideToItem( pos ); 762 763 } 764 765 }, 766 _slideToItem : function( pos ) { 767 768 // how much to slide? 769 var amount = this.options.orientation === 'horizontal' ? pos * this.$items.outerWidth( true ) : pos * this.$items.outerHeight( true ); 770 this._slide( '', -amount ); 771 772 }, 773 // public method: adds new items to the carousel
774 /* 775 776 how to use: 777 var carouselEl = $( '#carousel' ), 778 carousel = carouselEl.elastislide(); 779 ... 780 781 // append or prepend new items: 782 carouselEl.prepend('<li><a href="#"><img src="images/large/2.jpg" alt="image02" /></a></li>'); 783 784 // call the add method: 785 es.add(); 786 787 */ 788 add : function( callback ) { 789 790 var self = this, 791 oldcurrent = this.current, 792 $currentItem = this.$items.eq( this.current ); 793 794 // adds new items to the carousel 795 this.$items = this.$el.children( 'li' ); 796 this.itemsCount = this.$items.length; 797 this.current = $currentItem.index(); 798 this._setItemsSize(); 799 this._configure(); 800 this._removeTransition(); 801 oldcurrent < this.current ? this._slideToItem( this.current ) : this._slide( 'next', this.translation ); 802 setTimeout( function() { self._addTransition(); }, 25 ); 803 804 if ( callback ) { 805 806 callback.call(); 807 808 } 809 810 }, 811 // public method: sets a new element as the current. slides to that position 812 setCurrent : function( idx, callback ) { 813 814 this.current = idx; 815 816 this._slideTo(); 817 818 if ( callback ) { 819 820 callback.call(); 821 822 } 823 824 }, 825 // public method: slides to the next set of items 826 next : function() { 827 828 self._slide( 'next' ); 829 830 }, 831 // public method: slides to the previous set of items 832 previous : function() { 833 834 self._slide( 'prev' ); 835 836 }, 837 // public method: slides to the first item 838 slideStart : function() { 839 840 this._slideTo( 0 ); 841 842 }, 843 // public method: slides to the last item 844 slideEnd : function() { 845 846 this._slideTo( this.itemsCount - 1 ); 847 848 }, 849 // public method: destroys the elastislide instance 850 destroy : function( callback ) { 851 852 this._destroy( callback ); 853 854 } 855 856 }; 857 858 var logError = function( message ) { 859 860 if ( window.console ) { 861 862 window.console.error( message ); 863 864 } 865 866 }; 867 868 $.fn.elastislide = function( options ) { 869 870 var self = $.data( this, 'elastislide' ); 871 872 if ( typeof options === 'string' ) { 873 874 var args = Array.prototype.slice.call( arguments, 1 ); 875 876 this.each(function() { 877 878 if ( !self ) { 879 880 logError( "cannot call methods on elastislide prior to initialization; " + 881 "attempted to call method '" + options + "'" ); 882 return; 883 884 } 885 886 if ( !$.isFunction( self[options] ) || options.charAt(0) === "_" ) { 887 888 logError( "no such method '" + options + "' for elastislide self" ); 889 return; 890 891 } 892 893 self[ options ].apply( self, args ); 894 895 }); 896 897 } 898 else { 899 900 this.each(function() { 901 902 if ( self ) { 903 904 self._init(); 905 906 } 907 else { 908 909 self = $.data( this, 'elastislide', new $.Elastislide( options, this ) ); 910 911 } 912 913 }); 914 915 } 916 917 return self; 918 919 }; 920 921} )( jsnThemeStripjQuery, window );
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.