PageSourceSearch

https://www.downstateil.org/simplyscroll/jquery.simplyscroll.js

js downstateil.org collected 2026-09-28 09:34:37 UTC 13,235 bytes, 778 lines download raw bytes

1/*
2
3 * simplyScroll 2 - a scroll-tastic jQuery plugin
4
5 *
6
7 * http://logicbox.net/jquery/simplyscroll/
8
9 *
10
11 * Copyright (c) 2009-2012 Will Kelly - http://logicbox.net
12
13 *
14
15 * Dual licensed under the MIT and GPL licenses.
16
17 *
18
19 * Version: 2.0.5 Last revised: 10/05/2012
20
21 *
22
23 */
24
25
26
27(function($,window,undefined) {
28
29
30
31$.fn.simplyScroll = function(options) {
32
33	return this.each(function() {
34
35		new $.simplyScroll(this,options);
36
37	});
38
39};
40
41
42
43var defaults = {
44
45	customClass: 'simply-scroll',
46
47	frameRate: 24, //No of movements per second
48
49	speed: 1, //No of pixels per frame
50
51	orientation: 'horizontal', //'horizontal or 'vertical' - not to be confused with device orientation
52
53	auto: true,
54
55	autoMode: 'loop', //auto = true, 'loop' or 'bounce',
56
57	manualMode: 'end', //auto = false, 'loop' or 'end'
58
59	direction: 'forwards', //'forwards' or 'backwards'.
60
61	pauseOnHover: true, //autoMode = loop|bounce only
62
63	pauseOnTouch: true, //" touch device only
64
65	pauseButton: false, //" generates an extra element to allow manual pausing 
66
67	startOnLoad: false //use this to delay starting of plugin until all page assets have loaded
68
69};
70
71	
72
73$.simplyScroll = function(el,options) {
74
75	
76
77	var self = this;
78
79	
80
81	this.o = $.extend({}, defaults, options || {});
82
83	this.isAuto = this.o.auto!==false && this.o.autoMode.match(/^loop|bounce$/)!==null;
84
85	this.isHorizontal = this.o.orientation.match(/^horizontal|vertical$/)!==null && this.o.orientation==defaults.orientation; 
86
87	this.isRTL = this.isHorizontal && $("html").attr('dir') == 'rtl';
88
89	this.isForwards = !this.isAuto  || (this.isAuto && this.o.direction.match(/^forwards|backwards$/)!==null && this.o.direction==defaults.direction) && !this.isRTL;
90
91	this.isLoop = this.isAuto && this.o.autoMode == 'loop' || !this.isAuto && this.o.manualMode == 'loop';
92
93	
94
95	this.supportsTouch = ('createTouch' in document);
96
97	
98
99	this.events = this.supportsTouch ? 
100
101		{start:'touchstart MozTouchDown',move:'touchmove MozTouchMove',end:'touchend touchcancel MozTouchRelease'} : 
102
103		{start:'mouseenter',end:'mouseleave'};
104
105	
106
107	this.$list = $(el); //called on ul/ol/div etc
108
109	var $items = this.$list.children();
110
111	
112
113	//generate extra markup
114
115	this.$list.addClass('simply-scroll-list')
116
117		.wrap('<div class="simply-scroll-clip"></div>')
118
119		.parent().wrap('<div class="' + this.o.customClass + ' simply-scroll-container"></div>');
120
121	
122
123	if (!this.isAuto) { //button placeholders
124
125		this.$list.parent().parent()
126
127		.prepend('<div class="simply-scroll-forward"></div>')
128
129		.prepend('<div class="simply-scroll-back"></div>');
130
131	} else {
132
133		if (this.o.pauseButton) {
134
135			this.$list.parent().parent()
136
137			.prepend('<div class="simply-scroll-btn simply-scroll-btn-pause"></div>');
138
139			this.o.pauseOnHover = false;
140
141		}
142
143	}
144
145	
146
147	//wrap an extra div around the whole lot if elements scrolled aren't equal
148
149	if ($items.length > 1) {
150
151		
152
153		var extra_wrap = false,
154
155			total = 0;
156
157			
158
159		if (this.isHorizontal) {
160
161			$items.each(function() { total+=$(this).outerWidth(true); });
162
163			extra_wrap = $items.eq(0).outerWidth(true) * $items.length !== total;
164
165		} else {
166
167			$items.each(function() { total+=$(this).outerHeight(true); });
168
169			extra_wrap = $items.eq(0).outerHeight(true) * $items.length !== total;
170
171		}
172
173		
174
175		if (extra_wrap) {
176
177			this.$list = this.$list.wrap('<div></div>').parent().addClass('simply-scroll-list');
178
179			if (this.isHorizontal) {
180
181				this.$list.children().css({"float":'left',width: total + 'px'});	
182
183			} else {
184
185				this.$list.children().css({height: total + 'px'});
186
187			}
188
189		}
190
191	}
192
193	
194
195	if (!this.o.startOnLoad) {
196
197		this.init();
198
199	} else {
200
201		//wait for load before completing setup
202
203		$(window).load(function() { self.init();  });
204
205	}
206
207		
208
209};
210
211	
212
213$.simplyScroll.fn = $.simplyScroll.prototype = {};
214
215
216
217$.simplyScroll.fn.extend = $.simplyScroll.extend = $.extend;
218
219
220
221$.simplyScroll.fn.extend({
222
223	init: function() {
224
225
226
227		this.$items = this.$list.children();
228
229		this.$clip = this.$list.parent(); //this is the element that scrolls
230
231		this.$container = this.$clip.parent();
232
233		this.$btnBack = $('.simply-scroll-back',this.$container);
234
235		this.$btnForward = $('.simply-scroll-forward',this.$container);
236
237
238
239		if (!this.isHorizontal) {
240
241			this.itemMax = this.$items.eq(0).outerHeight(true); 
242
243			this.clipMax = this.$clip.height();
244
245			this.dimension = 'height';			
246
247			this.moveBackClass = 'simply-scroll-btn-up';
248
249			this.moveForwardClass = 'simply-scroll-btn-down';
250
251			this.scrollPos = 'Top';
252
253		} else {
254
255			this.itemMax = this.$items.eq(0).outerWidth(true);
256
257			this.clipMax = this.$clip.width();			
258
259			this.dimension = 'width';
260
261			this.moveBackClass = 'simply-scroll-btn-left';
262
263			this.moveForwardClass = 'simply-scroll-btn-right';
264
265			this.scrollPos = 'Left';
266
267		}
268
269		
270
271		this.posMin = 0;
272
273		
274
275		this.posMax = this.$items.length * this.itemMax;
276
277		
278
279		var addItems = Math.ceil(this.clipMax / this.itemMax);
280
281		
282
283		//auto scroll loop & manual scroll bounce or end(to-end)
284
285		if (this.isAuto && this.o.autoMode=='loop') {
286
287			
288
289			this.$list.css(this.dimension,this.posMax+(this.itemMax*addItems) +'px');
290
291			
292
293			this.posMax += (this.clipMax - this.o.speed);
294
295			
296
297			if (this.isForwards) {
298
299				this.$items.slice(0,addItems).clone(true).appendTo(this.$list);
300
301				this.resetPosition = 0;
302
303				
304
305			} else {
306
307				this.$items.slice(-addItems).clone(true).prependTo(this.$list);
308
309				this.resetPosition = this.$items.length * this.itemMax;
310
311				//due to inconsistent RTL implementation force back to LTR then fake
312
313				if (this.isRTL) {
314
315					this.$clip[0].dir = 'ltr';
316
317					//based on feedback seems a good idea to force float right
318
319					this.$items.css('float','right');
320
321				}
322
323			}
324
325		
326
327		//manual and loop
328
329		} else if (!this.isAuto && this.o.manualMode=='loop') {
330
331			
332
333			this.posMax += this.itemMax * addItems;
334
335			
336
337			this.$list.css(this.dimension,this.posMax+(this.itemMax*addItems) +'px');
338
339			
340
341			this.posMax += (this.clipMax - this.o.speed);
342
343			
344
345			var items_append  = this.$items.slice(0,addItems).clone(true).appendTo(this.$list);
346
347			var items_prepend = this.$items.slice(-addItems).clone(true).prependTo(this.$list);
348
349			
350
351			this.resetPositionForwards = this.resetPosition = addItems * this.itemMax;
352
353			this.resetPositionBackwards = this.$items.length * this.itemMax;
354
355			
356
357			//extra events to force scroll direction change
358
359			var self = this;
360
361			
362
363			this.$btnBack.bind(this.events.start,function() {
364
365				self.isForwards = false;
366
367				self.resetPosition = self.resetPositionBackwards;
368
369			});
370
371			
372
373			this.$btnForward.bind(this.events.start,function() {
374
375				self.isForwards = true;
376
377				self.resetPosition = self.resetPositionForwards;
378
379			});
380
381			
382
383		} else { //(!this.isAuto && this.o.manualMode=='end') 
384
385			
386
387			this.$list.css(this.dimension,this.posMax +'px');
388
389			
390
391			if (this.isForwards) {
392
393				this.resetPosition = 0;
394
395				
396
397			} else {
398
399				this.resetPosition = this.$items.length * this.itemMax;
400
401				//due to inconsistent RTL implementation force back to LTR then fake
402
403				if (this.isRTL) {
404
405					this.$clip[0].dir = 'ltr';
406
407					//based on feedback seems a good idea to force float right
408
409					this.$items.css('float','right');
410
411				}
412
413			}
414
415		}
416
417		
418
419		this.resetPos() //ensure scroll position is reset
420
421		
422
423		this.interval = null;	
424
425		this.intervalDelay = Math.floor(1000 / this.o.frameRate);
426
427		
428
429		if (!(!this.isAuto && this.o.manualMode=='end')) { //loop mode
430
431			//ensure that speed is divisible by item width. Helps to always make images even not odd widths!
432
433			while (this.itemMax % this.o.speed !== 0) {
434
435				this.o.speed--;
436
437				if (this.o.speed===0) {
438
439					this.o.speed=1; break;	
440
441				}
442
443			}
444
445		}
446
447		
448
449		var self = this;
450
451		this.trigger = null;
452
453		this.funcMoveBack = function(e) { 
454
455			if (e !== undefined) {
456
457				e.preventDefault();
458
459			}
460
461			self.trigger = !self.isAuto && self.o.manualMode=='end' ? this : null;
462
463			if (self.isAuto) {
464
465				self.isForwards ? self.moveBack() : self.moveForward(); 
466
467			} else {
468
469				self.moveBack();	
470
471			}
472
473		};
474
475		this.funcMoveForward = function(e) { 
476
477			if (e !== undefined) {
478
479				e.preventDefault();
480
481			}
482
483			self.trigger = !self.isAuto && self.o.manualMode=='end' ? this : null;
484
485			if (self.isAuto) {
486
487				self.isForwards ? self.moveForward() : self.moveBack(); 
488
489			} else {
490
491				self.moveForward();	
492
493			}
494
495		};
496
497		this.funcMovePause = function() { self.movePause(); };
498
499		this.funcMoveStop = function() { self.moveStop(); };
500
501		this.funcMoveResume = function() { self.moveResume(); };
502
503		
504
505		
506
507		
508
509		if (this.isAuto) {
510
511			
512
513			this.paused = false;
514
515			
516
517			function togglePause() {
518
519				if (self.paused===false) {
520
521					self.paused=true;
522
523					self.funcMovePause();
524
525				} else {
526
527					self.paused=false;
528
529					self.funcMoveResume();
530
531				}
532
533				return self.paused;
534
535			};
536
537			
538
539			//disable pauseTouch when links are present
540
541			if (this.supportsTouch && this.$items.find('a').length) {
542
543				this.supportsTouch=false;
544
545			}
546
547			
548
549			if (this.isAuto && this.o.pauseOnHover && !this.supportsTouch) {
550
551				this.$clip.bind(this.events.start,this.funcMovePause).bind(this.events.end,this.funcMoveResume);
552
553			} else if (this.isAuto && this.o.pauseOnTouch && !this.o.pauseButton && this.supportsTouch) {
554
555				
556
557				var touchStartPos, scrollStartPos;
558
559				
560
561				this.$clip.bind(this.events.start,function(e) {
562
563					togglePause();
564
565					var touch = e.originalEvent.touches[0];
566
567					touchStartPos = self.isHorizontal ? touch.pageX : touch.pageY;
568
569					scrollStartPos = self.$clip[0]['scroll' + self.scrollPos];
570
571					e.stopPropagation();
572
573					e.preventDefault();
574
575					
576
577				}).bind(this.events.move,function(e) {
578
579					
580
581					e.stopPropagation();
582
583					e.preventDefault();
584
585					
586
587					var touch = e.originalEvent.touches[0],
588
589						endTouchPos = self.isHorizontal ? touch.pageX : touch.pageY,
590
591						pos = (touchStartPos - endTouchPos) + scrollStartPos;
592
593					
594
595					if (pos < 0) pos = 0;
596
597					else if (pos > self.posMax) pos = self.posMax;
598
599					
600
601					self.$clip[0]['scroll' + self.scrollPos] = pos;
602
603					
604
605					//force pause
606
607					self.funcMovePause();
608
609					self.paused = true;
610
611				});	
612
613			} else {
614
615				if (this.o.pauseButton) {
616
617					
618
619					this.$btnPause = $(".simply-scroll-btn-pause",this.$container)
620
621						.bind('click',function(e) {
622
623							e.preventDefault();
624
625							togglePause() ? $(this).addClass('active') : $(this).removeClass('active');
626
627					});
628
629				}
630
631			}
632
633			this.funcMoveForward();
634
635		} else {
636
637
638
639			this.$btnBack 
640
641				.addClass('simply-scroll-btn' + ' ' + this.moveBackClass)
642
643				.bind(this.events.start,this.funcMoveBack).bind(this.events.end,this.funcMoveStop);
644
645			this.$btnForward
646
647				.addClass('simply-scroll-btn' + ' ' + this.moveForwardClass)
648
649				.bind(this.events.start,this.funcMoveForward).bind(this.events.end,this.funcMoveStop);
650
651				
652
653			if (this.o.manualMode == 'end') {
654
655				!this.isRTL ? this.$btnBack.addClass('disabled') : this.$btnForward.addClass('disabled');	
656
657			}
658
659		}
660
661	},
662
663	moveForward: function() {
664
665		var self = this;
666
667		this.movement = 'forward';
668
669		if (this.trigger !== null) {
670
671			this.$btnBack.removeClass('disabled');
672
673		}
674
675		self.interval = setInterval(function() {
676
677			if (self.$clip[0]['scroll' + self.scrollPos] < (self.posMax-self.clipMax)) {
678
679				self.$clip[0]['scroll' + self.scrollPos] += self.o.speed;
680
681			} else if (self.isLoop) {
682
683				self.resetPos();
684
685			} else {
686
687				self.moveStop(self.movement);
688
689			}
690
691		},self.intervalDelay);
692
693	},
694
695	moveBack: function() {
696
697		var self = this;
698
699		this.movement = 'back';
700
701		if (this.trigger !== null) {
702
703			this.$btnForward.removeClass('disabled');
704
705		}
706
707		self.interval = setInterval(function() {
708
709			if (self.$clip[0]['scroll' + self.scrollPos] > self.posMin) {
710
711				self.$clip[0]['scroll' + self.scrollPos] -= self.o.speed;
712
713			} else if (self.isLoop) {
714
715				self.resetPos();
716
717			} else {
718
719				self.moveStop(self.movement);
720
721			}
722
723		},self.intervalDelay);
724
725	},
726
727	movePause: function() {
728
729		clearInterval(this.interval);	
730
731	},
732
733	moveStop: function(moveDir) {
734
735		this.movePause();
736
737		if (this.trigger!==null) {
738
739			if (typeof moveDir !== 'undefined') {
740
741				$(this.trigger).addClass('disabled');
742
743			}
744
745			this.trigger = null;
746
747		}
748
749		if (this.isAuto) {
750
751			if (this.o.autoMode=='bounce') {
752
753				moveDir == 'forward' ? this.moveBack() : this.moveForward();
754
755			}
756
757		}
758
759	},
760
761	moveResume: function() {
762
763		this.movement=='forward' ? this.moveForward() : this.moveBack();
764
765	},
766
767	resetPos: function() {
768
769		this.$clip[0]['scroll' + this.scrollPos] = this.resetPosition;
770
771	}
772
773});
774
775		  
776
777})(jQuery,window);
778

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.