PageSourceSearch

https://www.bonbeachps.vic.edu.au/js_new/jquery.elastislide.js

js bonbeachps.vic.edu.au collected 2026-10-02 14:51:05 UTC 13,003 bytes, 467 lines download raw bytes

1(function( window, $, undefined ) {
2	
3	// http://www.netcu.de/jquery-touchwipe-iphone-ipad-library
4	$.fn.touchwipe 				= function(settings) {
5		
6		var config = {
7			min_move_x: 20,
8			min_move_y: 20,
9			wipeLeft: function() { },
10			wipeRight: function() { },
11			wipeUp: function() { },
12			wipeDown: function() { },
13			preventDefaultEvents: true
14		};
15     
16		if (settings) $.extend(config, settings);
17 
18		this.each(function() {
19			var startX;
20			var startY;
21			var isMoving = false;
22
23			function cancelTouch() {
24				this.removeEventListener('touchmove', onTouchMove);
25				startX = null;
26				isMoving = false;
27			}	
28		 
29			function onTouchMove(e) {
30				if(config.preventDefaultEvents) {
31					e.preventDefault();
32				}
33				if(isMoving) {
34					var x = e.touches[0].pageX;
35					var y = e.touches[0].pageY;
36					var dx = startX - x;
37					var dy = startY - y;
38					if(Math.abs(dx) >= config.min_move_x) {
39						cancelTouch();
40						if(dx > 0) {
41							config.wipeLeft();
42						}
43						else {
44							config.wipeRight();
45						}
46					}
47					else if(Math.abs(dy) >= config.min_move_y) {
48						cancelTouch();
49						if(dy > 0) {
50							config.wipeDown();
51						}
52						else {
53							config.wipeUp();
54						}
55					}
56				}
57			}
58		 
59			function onTouchStart(e)
60			{
61				if (e.touches.length == 1) {
62					startX = e.touches[0].pageX;
63					startY = e.touches[0].pageY;
64					isMoving = true;
65					this.addEventListener('touchmove', onTouchMove, false);
66				}
67			}    	 
68			if ('ontouchstart' in document.documentElement) {
69				this.addEventListener('touchstart', onTouchStart, false);
70			}
71		});
72 
73		return this;
74	};
75	
76	$.elastislide 				= function( options, element ) {
77		this.$el	= $( element );
78		this._init( options );
79	};
80	
81	$.elastislide.defaults 		= {
82		speed		: 450,	// animation speed
83		easing		: '',	// animation easing effect
84		imageW		: 190,	// the images width
85		margin		: 3,	// image margin right
86		border		: 2,	// image border
87		minItems	: 1,	// the minimum number of items to show. 
88							// when we resize the window, this will make sure minItems are always shown 
89							// (unless of course minItems is higher than the total number of elements)
90		current		: 0,	// index of the current item
91							// when we resize the window, the carousel will make sure this item is visible 
92		onClick		: function() { return false; } // click item callback
93    };
94	
95	$.elastislide.prototype 	= {
96		_init 				: function( options ) {
97			
98			this.options 		= $.extend( true, {}, $.elastislide.defaults, options );
99			
100			// <ul>
101			this.$slider		= this.$el.find('ul');
102			
103			// <li>
104			this.$items			= this.$slider.children('li');
105			
106			// total number of elements / images
107			this.itemsCount		= this.$items.length;
108			
109			// cache the <ul>'s parent, since we will eventually need to recalculate its width on window resize
110			this.$esCarousel	= this.$slider.parent();
111			
112			// validate options
113			this._validateOptions();
114			
115			// set sizes and initialize some vars...
116			this._configure();
117			
118			// add navigation buttons
119			this._addControls();
120			
121			// initialize the events
122			this._initEvents();
123			
124			// show the <ul>
125			this.$slider.show();
126			
127			// slide to current's position
128			this._slideToCurrent( false );
129			
130		},
131		_validateOptions	: function() {
132		
133			if( this.options.speed < 0 )
134				this.options.speed = 450;
135			if( this.options.margin < 0 )
136				this.options.margin = 4;
137			if( this.options.border < 0 )
138				this.options.border = 1;
139			if( this.options.minItems < 1 || this.options.minItems > this.itemsCount )
140				this.options.minItems = 1;
141			if( this.options.current > this.itemsCount - 1 )
142				this.options.current = 0;
143				
144		},
145		_configure			: function() {
146			
147			// current item's index
148			this.current		= this.options.current;
149			
150			// the ul's parent's (div.es-carousel) width is the "visible" width
151			this.visibleWidth	= this.$esCarousel.width();
152			
153			// test to see if we need to initially resize the items
154			if( this.visibleWidth < this.options.minItems * ( this.options.imageW + 2 * this.options.border ) + ( this.options.minItems - 1 ) * this.options.margin ) {
155				this._setDim( ( this.visibleWidth - ( this.options.minItems - 1 ) * this.options.margin ) / this.options.minItems );
156				this._setCurrentValues();
157				// how many items fit with the current width
158				this.fitCount	= this.options.minItems;
159			}
160			else {
161				this._setDim();
162				this._setCurrentValues();
163			}
164			
165			// set the <ul> width
166			this.$slider.css({
167				width	: this.sliderW
168			});
169			
170		},
171		_setDim				: function( elW ) {
172			
173			// <li> style
174			this.$items.css({
175				marginRight	: this.options.margin,
176				width		: ( elW ) ? elW : this.options.imageW + 2 * this.options.border
177			}).children('a').css({ // <a> style
178				borderWidth		: this.options.border
179			});
180			
181		},
182		_setCurrentValues	: function() {
183			
184			// the total space occupied by one item
185			this.itemW			= this.$items.outerWidth(true);
186			
187			// total width of the slider / <ul>
188			// this will eventually change on window resize
189			this.sliderW		= this.itemW * this.itemsCount;
190			
191			// the ul parent's (div.es-carousel) width is the "visible" width
192			this.visibleWidth	= this.$esCarousel.width();
193			
194			// how many items fit with the current width
195			this.fitCount		= Math.floor( this.visibleWidth / this.itemW );
196			
197		},
198		_addControls		: function() {
199			
200			this.$navNext	= $('<span class="es-nav-next">Next</span>');
201			this.$navPrev	= $('<span class="es-nav-prev">Previous</span>');
202			$('<div class="es-nav"/>')
203			.append( this.$navPrev )
204			.append( this.$navNext )
205			.appendTo( this.$el );
206			
207			//this._toggleControls();
208				
209		},
210		_toggleControls		: function( dir, status ) {
211			
212			// show / hide navigation buttons
213			if( dir && status ) {
214				if( status === 1 )
215					( dir === 'right' ) ? this.$navNext.show() : this.$navPrev.show();
216				else
217					( dir === 'right' ) ? this.$navNext.hide() : this.$navPrev.hide();
218			}
219			else if( this.current === this.itemsCount - 1 || this.fitCount >= this.itemsCount )
220					this.$navNext.hide();
221			
222		},
223		_initEvents			: function() {
224			
225			var instance	= this;
226			
227			// window resize
228			$(window).on('resize.elastislide', function( event ) {
229				
230				instance._reload();
231				
232				// slide to the current element
233				clearTimeout( instance.resetTimeout );
234				instance.resetTimeout	= setTimeout(function() {
235					instance._slideToCurrent();
236				}, 200);
237				
238			});
239			
240			// navigation buttons events
241			this.$navNext.on('click.elastislide', function( event ) {
242				instance._slide('right');
243			});
244			
245			this.$navPrev.on('click.elastislide', function( event ) {
246				instance._slide('left');
247			});
248			
249			// item click event
250			this.$slider.on('mouseover.elastislide', 'li', function( event ) {
251				instance.options.onClick( $(this) );
252				return false;
253			});
254			
255			// touch events
256			instance.$slider.touchwipe({
257				wipeLeft			: function() {
258					instance._slide('right');
259				},
260				wipeRight			: function() {
261					instance._slide('left');
262				}
263			});
264			
265		},
266		reload				: function( callback ) {
267			this._reload();
268			if ( callback ) callback.call();
269		
270		},
271		_reload				: function() {
272			
273			var instance	= this;
274			
275			// set values again
276			instance._setCurrentValues();
277			
278			// need to resize items
279			if( instance.visibleWidth < instance.options.minItems * ( instance.options.imageW + 2 * instance.options.border ) + ( instance.options.minItems - 1 ) * instance.options.margin ) {
280				instance._setDim( ( instance.visibleWidth - ( instance.options.minItems - 1 ) * instance.options.margin ) / instance.options.minItems );
281				instance._setCurrentValues();
282				instance.fitCount	= instance.options.minItems;
283			}	
284			else{
285				instance._setDim();
286				instance._setCurrentValues();
287			}
288			
289			instance.$slider.css({
290				width	: instance.sliderW + 10 // TODO: +10px seems to solve a firefox "bug" :S
291			});
292			
293		},
294		_slide				: function( dir, val, anim, callback ) {
295			
296			// if animating return
297			//if( this.$slider.is(':animated') )
298				//return false;
299			
300			// current margin left
301			var ml		= parseFloat( this.$slider.css('margin-left') );
302			
303			// val is just passed when we want an exact value for the margin left (used in the _slideToCurrent function)
304			if( val === undefined ) {
305			
306				// how much to slide?
307				var amount	= this.fitCount * this.itemW, val;
308				
309				if( amount < 0 ) return false;
310				
311				// make sure not to leave a space between the last item / first item and the end / beggining of the slider available width
312				if( dir === 'right' && this.sliderW - ( Math.abs( ml ) + amount ) < this.visibleWidth ) {
313					amount	= this.sliderW - ( Math.abs( ml ) + this.visibleWidth ) - this.options.margin; // decrease the margin left
314					// show / hide navigation buttons
315					this._toggleControls( 'right', -1 );
316					this._toggleControls( 'left', 1 );
317				}
318				else if( dir === 'left' && Math.abs( ml ) - amount < 0 ) {				
319					amount	= Math.abs( ml );
320					// show / hide navigation buttons
321					this._toggleControls( 'left', -1 );
322					this._toggleControls( 'right', 1 );
323				}
324				else {
325					var fml; // future margin left
326					( dir === 'right' ) 
327						? fml = Math.abs( ml ) + this.options.margin + Math.abs( amount ) 
328						: fml = Math.abs( ml ) - this.options.margin - Math.abs( amount );
329					
330					// show / hide navigation buttons
331					if( fml > 0 )
332						this._toggleControls( 'left', 1 );
333					else	
334						this._toggleControls( 'left', -1 );
335					
336					if( fml < this.sliderW - this.visibleWidth )
337						this._toggleControls( 'right', 1 );
338					else	
339						this._toggleControls( 'right', -1 );
340						
341				}
342				
343				( dir === 'right' ) ? val = '-=' + amount : val = '+=' + amount
344				
345			}
346			else {
347				var fml		= Math.abs( val ); // future margin left
348				
349				if( Math.max( this.sliderW, this.visibleWidth ) - fml < this.visibleWidth ) {
350					val	= - ( Math.max( this.sliderW, this.visibleWidth ) - this.visibleWidth );
351					if( val !== 0 )
352						val += this.options.margin;	// decrease the margin left if not on the first position
353						
354					// show / hide navigation buttons
355					this._toggleControls( 'right', -1 );
356					fml	= Math.abs( val );
357				}
358				
359				// show / hide navigation buttons
360				if( fml > 0 )
361					this._toggleControls( 'left', 1 );
362				else
363					this._toggleControls( 'left', -1 );
364				
365				if( Math.max( this.sliderW, this.visibleWidth ) - this.visibleWidth > fml + this.options.margin )	
366					this._toggleControls( 'right', 1 );
367				else
368					this._toggleControls( 'right', -1 );
369					
370			}
371			
372			$.fn.applyStyle = ( anim === undefined ) ? $.fn.animate : $.fn.css;
373			
374			var sliderCSS	= { marginLeft : val };
375			
376			var instance	= this;
377			
378			this.$slider.stop().applyStyle( sliderCSS, $.extend( true, [], { duration : this.options.speed, easing : this.options.easing, complete : function() {
379				if( callback ) callback.call();
380			} } ) );
381			
382		},
383		_slideToCurrent		: function( anim ) {
384			
385			// how much to slide?
386			var amount	= this.current * this.itemW;
387			this._slide('', -amount, anim );
388			
389		},
390		add					: function( $newelems, callback ) {
391			
392			// adds new items to the carousel
393			this.$items 		= this.$items.add( $newelems );
394			this.itemsCount		= this.$items.length;
395			this._setDim();
396			this._setCurrentValues();
397			this.$slider.css({
398				width	: this.sliderW
399			});
400			this._slideToCurrent();
401			
402			if ( callback ) callback.call( $newelems );
403			
404		},
405		setCurrent			: function( idx, callback ) {
406			
407			this.current = idx;
408			
409			var ml		= Math.abs( parseFloat( this.$slider.css('margin-left') ) ),
410				posR	= ml + this.visibleWidth,
411				fml		= Math.abs( this.current * this.itemW );
412			
413			if( fml + this.itemW > posR || fml < ml ) {
414				this._slideToCurrent();
415			}
416			
417			if ( callback ) callback.call();
418			
419		},
420		destroy				: function( callback ) {
421			
422			this._destroy( callback );
423			
424		},
425		_destroy 			: function( callback ) {
426			this.$el.off('.elastislide').removeData('elastislide');
427			$(window).off('.elastislide');
428			if ( callback ) callback.call();
429		}
430	};
431	
432	var logError 				= function( message ) {
433		if ( this.console ) {
434			console.error( message );
435		}
436	};
437	
438	$.fn.elastislide 				= function( options ) {
439		if ( typeof options === 'string' ) {
440			var args = Array.prototype.slice.call( arguments, 1 );
441
442			this.each(function() {
443				var instance = $.data( this, 'elastislide' );
444				if ( !instance ) {
445					logError( "cannot call methods on elastislide prior to initialization; " +
446					"attempted to call method '" + options + "'" );
447					return;
448				}
449				if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
450					logError( "no such method '" + options + "' for elastislide instance" );
451					return;
452				}
453				instance[ options ].apply( instance, args );
454			});
455		} 
456		else {
457			this.each(function() {
458				var instance = $.data( this, 'elastislide' );
459				if ( !instance ) {
460					$.data( this, 'elastislide', new $.elastislide( options, this ) );
461				}
462			});
463		}
464		return this;
465	};
466	
467})( window, jQuery );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.