PageSourceSearch

https://www.steveferris.com/js/elastislide/js/jquery.elastislide.js

js steveferris.com collected 2026-09-27 04:29:37 UTC 25,398 bytes, 951 lines download raw bytes

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
26	var $event = $.event,
27	$special,
28	resizeTimeout;
29
30	$special = $event.special.debouncedresize = {
31		setup: function() {
32			$( this ).on( "resize", $special.handler );
33		},
34		teardown: function() {
35			$( this ).off( "resize", $special.handler );
36		},
37		handler: function( event, execAsap ) {
38			// Save the context
39			var context = this,
40				args = arguments,
41				dispatch = function() {
42					// set correct event type
43					event.type = "debouncedresize";
44					$event.dispatch.apply( context, args );
45				};
46
47			if ( resizeTimeout ) {
48				clearTimeout( resizeTimeout );
49			}
50
51			execAsap ?
52				dispatch() :
53				resizeTimeout = setTimeout( dispatch, $special.threshold );
54		},
55		threshold: 150
56	};
57
58	// ======================= imagesLoaded Plugin ===============================
59	// https://github.com/desandro/imagesloaded
60
61	// $('#my-container').imagesLoaded(myFunction)
62	// execute a callback when all images have loaded.
63	// needed because .load() doesn't work on cached images
64
65	// callback function gets image collection as argument
66	//  this is the container
67
68	// original: mit license. paul irish. 2010.
69	// contributors: Oren Solomianik, David DeSandro, Yiannis Chatzikonstantinou
70
71	// blank image data-uri bypasses webkit log warning (thx doug jones)
72	var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
73
74	$.fn.imagesLoaded = function( callback ) {
75		var $this = this,
76			deferred = $.isFunction($.Deferred) ? $.Deferred() : 0,
77			hasNotify = $.isFunction(deferred.notify),
78			$images = $this.find('img').add( $this.filter('img') ),
79			loaded = [],
80			proper = [],
81			broken = [];
82
83		// Register deferred callbacks
84		if ($.isPlainObject(callback)) {
85			$.each(callback, function (key, value) {
86				if (key === 'callback') {
87					callback = value;
88				} else if (deferred) {
89					deferred[key](value);
90				}
91			});
92		}
93
94		function doneLoading() {
95			var $proper = $(proper),
96				$broken = $(broken);
97
98			if ( deferred ) {
99				if ( broken.length ) {
100					deferred.reject( $images, $proper, $broken );
101				} else {
102					deferred.resolve( $images );
103				}
104			}
105
106			if ( $.isFunction( callback ) ) {
107				callback.call( $this, $images, $proper, $broken );
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		console.log("init complete");
190
191	};
192
193	$.Elastislide.defaults = {
194		// orientation 'horizontal' || 'vertical'
195		orientation : 'horizontal',
196		// sliding speed
197		speed : 500,
198		// sliding easing
199		easing : 'ease-in-out',
200		// the minimum number of items to show.
201		// when we resize the window, this will make sure minItems are always shown
202		// (unless of course minItems is higher than the total number of elements)
203		minItems : 3,
204		// optionally specify a selector rather than using the img element to read the image sizes
205		// (we only use the first matching element within our items)
206		imgSizeItemSelector : 'img',
207		// index of the current item (left most item of the carousel)
208		start : 0,
209		// autoslide feature: true || false
210		// automatically loops through the carousel (after hitting the end of the list goes back to front)
211		// disabled by default
212		autoSlide: false,
213		// autoslide delay time, specifies time interval between autoslide steps (in milliseconds)
214		// 3000ms by default
215		delayTime: 3000,
216		// click item callback
217		onClick : function( el, position, evt ) { return false; },
218		onReady : function() { return false; },
219		onBeforeSlide : function() { return false; },
220		onAfterSlide : function() { return false; }
221	};
222
223	$.Elastislide.prototype = {
224
225		_init : function( options ) {
226
227			// options
228			this.options = $.extend( true, {}, $.Elastislide.defaults, options );
229
230			// https://github.com/twitter/bootstrap/issues/2870
231			var self = this,
232				transEndEventNames = {
233					'WebkitTransition' : 'webkitTransitionEnd',
234					'MozTransition' : 'transitionend',
235					'OTransition' : 'oTransitionEnd',
236					'msTransition' : 'MSTransitionEnd',
237					'transition' : 'transitionend'
238				};
239
240			this.transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ];
241
242			// suport for css transforms and css transitions
243			this.support = Modernizr.csstransitions && Modernizr.csstransforms;
244
245			// current item's index
246			this.current = this.options.start;
247
248			// control if it's sliding
249			this.isSliding = false;
250
251			this.$items = this.$el.children( 'li' );
252			// total number of items
253			this.itemsCount = this.$items.length;
254
255			console.log("elastislide init with "+this.$items.length+" images");
256			if( this.itemsCount === 0 ) {
257
258				return false;
259
260			}
261			this._validate();
262			// remove white space
263			this.$items.detach();
264			this.$el.empty();
265			this.$el.append( this.$items );
266
267			// main wrapper
268			this.$el.wrap( '<div class="elastislide-wrapper elastislide-loading elastislide-' + this.options.orientation + '"></div>' );
269
270			// check if we applied a transition to the <ul>
271			this.hasTransition = false;
272
273			// add transition for the <ul>
274			this.hasTransitionTimeout = setTimeout( function() {
275
276				self._addTransition();
277
278			}, 100 );
279
280			// preload the images
281
282			this.$el.imagesLoaded( function() {
283
284				self.$el.show();
285
286				self._layout();
287				self._configure();
288
289				if( self.hasTransition ) {
290
291					console.log("Has transition and sliding"); clearTimeout( self.hasTransitionTimeout );
292
293					//Eric, the below callback wasn't running, so run it manually here:
294					// slide to current's position
295					self._removeTransition();
296					self._slideToItem( self.current );
297
298					self.$el.off( self.transEndEventName );
299					self._setWrapperSize();
300					// add transition for the <ul>
301					self._addTransition();
302					self._initEvents();
303
304					/*
305					self.$el.on( self.transEndEventName, function() {
306
307						console.log("running callback");
308						self.$el.off( self.transEndEventName );
309						self._setWrapperSize();
310						// add transition for the <ul>
311						self._addTransition();
312						self._initEvents();
313
314					} );
315					*/
316
317				}
318				else {
319
320					console.log("Doesn't have transition");
321
322					clearTimeout( self.hasTransitionTimeout );
323					self._setWrapperSize();
324					self._initEvents();
325					// slide to current's position
326					self._slideToItem( self.current );
327					setTimeout( function() { self._addTransition(); }, 25 );
328
329				}
330
331				self.options.onReady(self.$el);
332
333			} );
334
335		},
336		_validate : function() {
337
338
339  			if( this.options.minItems instanceof Function ) {
340
341  		  		this._minItemsFn = this.options.minItems;
342  		  		this.options.minItems = this.options.minItems( document.documentElement.clientWidth );
343
344  			}
345
346
347
348			if( this.options.speed < 0 ) {
349
350				this.options.speed = 500;
351
352			}
353			if( this.options.minItems < 1 || this.options.minItems > this.itemsCount ) {
354
355				this.options.minItems = 1;
356
357			}
358			if( this.options.start < 0 || this.options.start > this.itemsCount - 1 ) {
359
360				this.options.start = 0;
361
362			}
363			if( this.options.orientation != 'horizontal' && this.options.orientation != 'vertical' ) {
364
365				this.options.orientation = 'horizontal';
366
367			}
368
369		},
370		_layout : function() {
371
372			this.$el.wrap( '<div class="elastislide-carousel"></div>' );
373
374			this.$carousel = this.$el.parent();
375			this.$wrapper = this.$carousel.parent().removeClass( 'elastislide-loading' );
376
377			// save original image sizes
378			var $img = this.$items.find( this.options.imgSizeItemSelector ).first();
379			this.imgSize = { width : $img.outerWidth( true ), height : $img.outerHeight( true ) };
380
381			this._setItemsSize();
382			this.options.orientation === 'horizontal' ? this.$el.css( 'max-height', this.imgSize.height ) : this.$el.css( 'height', this.options.minItems * this.imgSize.height );
383
384			// add the controls
385			this._addControls();
386
387		},
388		_addTransition : function() {
389
390			if( this.support ) {
391
392				this.$el.css( 'transition', 'all ' + this.options.speed + 'ms ' + this.options.easing );
393
394			}
395			this.hasTransition = true;
396
397		},
398		_removeTransition : function() {
399
400			if( this.support ) {
401
402				this.$el.css( 'transition', 'all 0s' );
403
404			}
405			this.hasTransition = false;
406
407		},
408		_addControls : function() {
409
410			var self = this;
411
412			// add navigation elements
413			this.$navigation = $( '<nav><span class="elastislide-prev">Previous</span><span class="elastislide-next">Next</span></nav>' )
414				.appendTo( this.$wrapper );
415
416
417			this.$navPrev = this.$navigation.find( 'span.elastislide-prev' ).on( 'mousedown.elastislide', function( event ) {
418
419				self._slide( 'prev' );
420				return false;
421
422			} );
423
424			this.$navNext = this.$navigation.find( 'span.elastislide-next' ).on( 'mousedown.elastislide', function( event ) {
425
426				self._slide( 'next' );
427				return false;
428
429			} );
430
431		},
432		_setItemsSize : function() {
433
434			// width for the items (%)
435			var w = this.options.orientation === 'horizontal' ? ( Math.floor( this.$carousel.width() / this.options.minItems ) * 100 ) / this.$carousel.width() : 100;
436
437			console.log("w="+w);
438
439			this.$items.css( {
440				'width' : w + '%',
441				'max-width' : this.imgSize.width,
442				'max-height' : this.imgSize.height
443			} );
444
445			if( this.options.orientation === 'vertical' ) {
446
447				//bug fix for Windows, IE and Firefox. For some reason it was grabbing the wrong widths. This was called earlier in the setup process, but I guess the DOM hadn't finished updating yet, so we are calling the exact same code again. Problem solved.
448				var $img = this.$items.find( this.options.imgSizeItemSelector ).first();
449				this.imgSize = { width : $img.outerWidth( true ), height : $img.outerHeight( true ) };
450
451				//how many images can fit across? size of space divided by size of images.
452				//no longer using this.options.verticalColumns, was getting bugs, maybe memcached??
453				this.$maxImageFit = Math.floor( this.$carousel.parent().parent().width() / this.imgSize.width );
454
455				console.log("this.imgSize.width="+this.imgSize.width);
456				console.log("this.$carousel.parent().parent().width()="+this.$carousel.parent().parent().width());
457				console.log("maxImageFit="+this.$maxImageFit);
458
459				console.log(this.$carousel.parent().parent());
460				console.log(this.$items.find( this.options.imgSizeItemSelector ).first().width());
461				console.log("this.$wrapper.width="+this.$wrapper.width());
462				console.log("this.$wrapper=...");
463				console.log(this.$wrapper);
464				console.log("how many images can fit across="+Math.floor( this.$carousel.width() / this.imgSize.width ));
465
466				//eric set max-width based on number image columns
467				this.$wrapper.css( 'max-width', (this.imgSize.width * this.$maxImageFit) + parseInt( this.$wrapper.css( 'padding-left' ) ) + parseInt( this.$wrapper.css( 'padding-right' ) ) );
468
469				//this.$wrapper.css( 'max-width', this.imgSize.width + parseInt( this.$wrapper.css( 'padding-left' ) ) + parseInt( this.$wrapper.css( 'padding-right' ) ) );
470
471			}
472
473		},
474		_setWrapperSize : function() {
475
476			if( this.options.orientation === 'vertical' ) {
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' ) )
480				} );
481
482			}
483
484		},
485		_configure : function() {
486
487			// check how many items fit in the carousel (visible area -> this.$carousel.width() )
488			this.fitCount = this.options.orientation === 'horizontal' ?
489								this.$carousel.width() < this.options.minItems * this.imgSize.width ? this.options.minItems : Math.floor( this.$carousel.width() / this.imgSize.width ) :
490								this.$carousel.height() < this.options.minItems * this.imgSize.height ? this.options.minItems : Math.floor( this.$carousel.height() / this.imgSize.height );
491
492		},
493		_initEvents : function() {
494
495			var self = this;
496			//autoslide. To enablethis, set "var autoSlide" to "true" above.
497			if( this.options.autoSlide ) {
498				var translation = 0;
499				// width/height of an item ( <li> )
500				var itemSpace = this.options.orientation === 'horizontal' ? this.$items.outerWidth( true ) : this.$items.outerHeight( true );
501				// total width/height of the <ul>
502				var totalSpace = this.itemsCount * itemSpace;
503				// visible width/height
504				var visibleSpace = this.options.orientation === 'horizontal' ? this.$carousel.width() : this.$carousel.height();
505				window.setInterval(function(){
506				    //test if we should go to next slide or return to first slide
507				    if(totalSpace > translation + visibleSpace)
508				    {
509				        self._slide('next');
510				        translation += visibleSpace;
511				    }
512				    else
513				    {
514				        self._slideTo(0);
515				        translation = 0;
516				    }
517				}, this.options.delayTime);
518			}
519
520			$window.on( 'debouncedresize.elastislide', function() {
521
522				if( self._minItemsFn ) {
523				  self.options.minItems = self._minItemsFn( document.documentElement.clientWidth );
524				}
525
526
527				self._setItemsSize();
528				self._configure();
529				self._slideToItem( self.current );
530
531			} );
532
533			this.$el.on( this.transEndEventName, function() {
534
535				self._onEndTransition();
536
537			} );
538
539			if( this.options.orientation === 'horizontal' ) {
540
541				this.$el.on( {
542					swipeleft : function() {
543
544						self._slide( 'next' );
545
546					},
547					swiperight : function() {
548
549						self._slide( 'prev' );
550
551					}
552				} );
553
554			}
555			else {
556
557				this.$el.on( {
558					swipeup : function() {
559
560						self._slide( 'next' );
561
562					},
563					swipedown : function() {
564
565						self._slide( 'prev' );
566
567					}
568				} );
569
570			}
571
572			// item click event
573			this.$el.on( 'click.elastislide', 'li', function( event ) {
574
575				var $item = $( this );
576
577				self.options.onClick( $item, $item.index(), event );
578
579			});
580
581		},
582		_destroy : function( callback ) {
583
584			this.$el.off( this.transEndEventName ).off( 'swipeleft swiperight swipeup swipedown .elastislide' );
585			$window.off( '.elastislide' );
586
587			this.$el.css( {
588				'max-height' : 'none',
589				'transition' : 'none'
590			} ).unwrap( this.$carousel ).unwrap( this.$wrapper );
591
592			this.$items.css( {
593				'width' : 'auto',
594				'max-width' : 'none',
595				'max-height' : 'none'
596			} );
597
598			this.$navigation.remove();
599			this.$wrapper.remove();
600
601			if( callback ) {
602
603				callback.call();
604
605			}
606
607		},
608		_toggleControls : function( dir, display ) {
609
610			if( display ) {
611
612				( dir === 'next' ) ? this.$navNext.show() : this.$navPrev.show();
613
614			}
615			else {
616
617				( dir === 'next' ) ? this.$navNext.hide() : this.$navPrev.hide();
618
619			}
620
621		},
622		_slide : function( dir, tvalue ) {
623
624			if( this.isSliding ) {
625				console.log("is sliding");
626				return false;
627
628			}
629
630			this.options.onBeforeSlide();
631
632			this.isSliding = true;
633
634			var self = this,
635				translation = this.translation || 0,
636				// width/height of an item ( <li> )
637				itemSpace = this.options.orientation === 'horizontal' ? this.$items.outerWidth( true ) : this.$items.outerHeight( true );
638
639				// eric calculate the total height of the thumbnail div taking into account vertical columns
640				if(this.$maxImageFit == 1)
641				{
642					var verticalCount = this.itemsCount;
643					console.log("1 vertical column");
644				} else {
645						console.log("more than 1 vertical column");
646					// check if the total number of images is divisible by the about of columns
647					// console.log("this.itemsCount="+this.itemsCount+", this.options.verticalColumns="+this.options.verticalColumns);
648					if (this.itemsCount%this.$maxImageFit == 1)
649					{
650						//number is not divisible
651						console.log('odd');
652						var verticalCount = parseInt(this.itemsCount / this.$maxImageFit)+1;
653					} else {
654						//number is divisible,
655						var verticalCount = this.itemsCount / this.$maxImageFit;
656						console.log('even');
657					}
658				}
659				console.log("verticalCount="+verticalCount);
660
661				// total width/height of the <ul>
662				//var totalSpace = this.itemsCount * itemSpace,
663				var totalSpace = verticalCount * itemSpace,
664
665				// visible width/height
666				visibleSpace = this.options.orientation === 'horizontal' ? this.$carousel.width() : this.$carousel.height();
667
668			if( tvalue === undefined ) {
669
670				var amount = this.fitCount * itemSpace;
671
672				if( amount < 0 ) {
673					console.log("amount less than zero");
674					return false;
675
676				}
677
678				if( dir === 'next' && totalSpace - ( Math.abs( translation ) + amount ) < visibleSpace ) {
679
680					amount = totalSpace - ( Math.abs( translation ) + visibleSpace );
681
682					// show / hide navigation buttons
683					this._toggleControls( 'next', false );
684					this._toggleControls( 'prev', true );
685
686				}
687				else if( dir === 'prev' && Math.abs( translation ) - amount < 0 ) {
688
689					amount = Math.abs( translation );
690
691					// show / hide navigation buttons
692					this._toggleControls( 'next', true );
693					this._toggleControls( 'prev', false );
694
695				}
696				else {
697
698					// future translation value
699					var ftv = dir === 'next' ? Math.abs( translation ) + Math.abs( amount ) : Math.abs( translation ) - Math.abs( amount );
700
701					// show / hide navigation buttons
702					ftv > 0 ? this._toggleControls( 'prev', true ) : this._toggleControls( 'prev', false );
703					ftv < totalSpace - visibleSpace ? this._toggleControls( 'next', true ) : this._toggleControls( 'next', false );
704
705				}
706
707				tvalue = dir === 'next' ? translation - amount : translation + amount;
708
709			}
710			else {
711
712				var amount = Math.abs( tvalue );
713
714				if( Math.max( totalSpace, visibleSpace ) - amount < visibleSpace ) {
715
716					tvalue	= - ( Math.max( totalSpace, visibleSpace ) - visibleSpace );
717
718				}
719
720				// show / hide navigation buttons
721				amount > 0 ? this._toggleControls( 'prev', true ) : this._toggleControls( 'prev', false );
722				Math.max( totalSpace, visibleSpace ) - visibleSpace > amount ? this._toggleControls( 'next', true ) : this._toggleControls( 'next', false );
723
724			}
725
726			this.translation = tvalue;
727
728			if( translation === tvalue ) {
729
730				this._onEndTransition();
731				console.log("endtransition");
732				return false;
733
734			}
735
736			if( this.support ) {
737
738		                if (this.options.orientation === 'horizontal') {
739		                    this.$el.css( '-webkit-transform', 'translateX(' + tvalue + 'px)' );
740		                    this.$el.css( '-o-transform', 'translateX(' + tvalue + 'px)' );
741		                    this.$el.css( '-ms-transform', 'translateX(' + tvalue + 'px)' );
742		                    this.$el.css( '-moz-transform', 'translateX(' + tvalue + 'px)' );
743		                    this.$el.css( 'transform', 'translateX(' + tvalue + 'px)' );
744		                } else {
745		                    this.$el.css( '-webkit-transform', 'translateY(' + tvalue + 'px)' );
746		                    this.$el.css( '-o-transform', 'translateY(' + tvalue + 'px)' );
747		                    this.$el.css( '-ms-transform', 'translateY(' + tvalue + 'px)' );
748		                    this.$el.css( '-moz-transform', 'translateY(' + tvalue + 'px)' );
749		                    this.$el.css( 'transform', 'translateY(' + tvalue + 'px)' );
750		                }
751
752			}
753			else {
754
755				$.fn.applyStyle = this.hasTransition ? $.fn.animate : $.fn.css;
756				var styleCSS = this.options.orientation === 'horizontal' ? { left : tvalue } : { top : tvalue };
757
758				this.$el.stop().applyStyle( styleCSS, $.extend( true, [], { duration : this.options.speed, complete : function() {
759
760					self._onEndTransition();
761
762				} } ) );
763
764			}
765
766			if( !this.hasTransition ) {
767
768				this._onEndTransition();
769
770			}
771
772		},
773		_onEndTransition : function() {
774
775			this.isSliding = false;
776			this.options.onAfterSlide();
777
778		},
779		_slideTo : function( pos ) {
780
781			var pos = pos || this.current,
782				translation = Math.abs( this.translation ) || 0,
783				itemSpace = this.options.orientation === 'horizontal' ? this.$items.outerWidth( true ) : this.$items.outerHeight( true ),
784				posR = translation + this.$carousel.width(),
785				ftv = Math.abs( pos * itemSpace );
786
787			if( ftv + itemSpace > posR || ftv < translation ) {
788
789				this._slideToItem( pos );
790
791			}
792
793		},
794		_slideToItem : function( pos ) {
795
796			// how much to slide?
797			var amount	= this.options.orientation === 'horizontal' ? pos * this.$items.outerWidth( true ) : pos * this.$items.outerHeight( true );
798			this._slide( '', -amount );
799
800		},
801		// public method: adds new items to the carousel
802		/*
803
804		how to use:
805		var carouselEl = $( '#carousel' ),
806			carousel = carouselEl.elastislide();
807		...
808
809		// append or prepend new items:
810		carouselEl.prepend('<li><a href="#"><img src="images/large/2.jpg" alt="image02" /></a></li>');
811
812		// call the add method:
813		es.add();
814
815		*/
816		add : function( callback ) {
817
818			var self = this,
819				oldcurrent = this.current,
820				$currentItem = this.$items.eq( this.current );
821
822			// adds new items to the carousel
823			this.$items = this.$el.children( 'li' );
824			this.itemsCount = this.$items.length;
825			this.current = $currentItem.index();
826			this._setItemsSize();
827			this._configure();
828			this._removeTransition();
829			oldcurrent < this.current ? this._slideToItem( this.current ) : this._slide( 'next', this.translation );
830			setTimeout( function() { self._addTransition(); }, 25 );
831
832			if ( callback ) {
833
834				callback.call();
835
836			}
837
838		},
839		// public method: sets a new element as the current. slides to that position
840		setCurrent : function( idx, callback ) {
841
842			this.current = idx;
843
844			this._slideTo();
845
846			if ( callback ) {
847
848				callback.call();
849
850			}
851
852		},
853		// public method: slides to the next set of items
854		next : function() {
855
856			this._slide( 'next' );
857
858		},
859		// public method: slides to the previous set of items
860		previous : function() {
861
862			this._slide( 'prev' );
863
864		},
865		// public method: slides to the first item
866		slideStart : function() {
867
868			this._slideTo( 0 );
869
870		},
871		// public method: slides to the last item
872		slideEnd : function() {
873
874			this._slideTo( this.itemsCount - 1 );
875
876		},
877		// public method: destroys the elastislide instance
878		destroy : function( callback ) {
879
880			this._destroy( callback );
881
882		}
883
884	};
885
886	var logError = function( message ) {
887
888		if ( window.console ) {
889
890			window.console.error( message );
891
892		}
893
894	};
895
896	$.fn.elastislide = function( options ) {
897
898		if ( typeof options === 'string' ) {
899
900			var args = Array.prototype.slice.call( arguments, 1 );
901
902			this.each(function() {
903
904				var self = $.data( this, 'elastislide' );
905
906				if ( !self ) {
907
908					logError( "cannot call methods on elastislide prior to initialization; " +
909					"attempted to call method '" + options + "'" );
910					return;
911
912				}
913
914				if ( !$.isFunction( self[options] ) || options.charAt(0) === "_" ) {
915
916					logError( "no such method '" + options + "' for elastislide self" );
917					return;
918
919				}
920
921				self[ options ].apply( self, args );
922
923			});
924
925		}
926		else {
927
928			this.each(function() {
929
930				var self = $.data( this, 'elastislide' );
931
932				if ( self ) {
933
934					self._init();
935
936				}
937				else {
938
939					self = $.data( this, 'elastislide', new $.Elastislide( options, this ) );
940
941				}
942
943			});
944
945		}
946
947		return self;
948
949	};
950
951} )( jQuery, 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.