PageSourceSearch

https://us.iahv.org/wp-content/themes/thestory/js/content-slider.js?ver=1.9.1

js iahv.org collected 2026-09-24 18:03:51 UTC 19,681 bytes, 835 lines download raw bytes

1function onYouTubeIframeAPIReady(){
2	if(PEXETO.pendingVideoFunctions && PEXETO.pendingVideoFunctions.length){
3		for(var i in PEXETO.pendingVideoFunctions){
4			PEXETO.pendingVideoFunctions[i].call();
5		}
6	}
7}
8
9
10/**
11 * This is the script for the content slider - it slides between different slides with
12 * different animation. Each slide is composed of two sections and each of this section
13 * is animated in a random effect.
14 *
15 * Dependencies:
16 * - jQuery
17 * - jQuery Easing : http://gsgd.co.uk/sandbox/jquery/easing/
18 *
19 * @author Pexeto
20 * http://pexetothemes.com
21 */
22(function($) {
23	"use strict";
24	
25	$.fn.pexetoContentSlider = function(options) {
26		var defaults = {
27			//set the default options (can be overwritten from the calling function)
28			autoplay          : true,
29			autoplayMobile    : false,
30			animationInterval : 5000,
31			//the interval between each animation when autoplay is true
32			pauseOnHover      : true,
33			//if true the animation will be paused when the mouse is
34			// over the slider
35			pauseInterval     : 5000,
36			//the time that the animation will be paused after a click
37			animationSpeed    : 400,
38			easing            : 'easeOutSine',
39			buttons           : true,
40			//show the navigation buttons
41			arrows            : true,
42			thumbnailPreview  : true,
43			//show the navigation arrows
44			//selectors, classes and IDs
45			ulSel             : '#cs-slider-ul',
46			navigationId      : 'cs-navigation',
47			selectedClass     : 'selected',
48			firstBoxSel       : '.cs-content-left',
49			secondBoxSel      : '.cs-content-right',
50			centerBoxSel	  : '.cs-content-centered',
51			prevArrowClass    : 'cs-arrows cs-prev-arrow',
52			nextArrowClass    : 'cs-arrows cs-next-arrow',
53			loadingClass      : 'cs-loading'
54		};
55
56
57		var o            = $.extend(defaults, options),
58			$root        = null,
59			$parent      = null,
60			$ul          = null,
61			$nav         = null,
62			$navLi       = null,
63			$prevArrow   = null,
64			$nextArrow   = null,
65			itemNum      = 0,
66			currentIndex = 0,
67			timer        = 0,
68			stopped      = true,
69			inAnimation  = false,
70			sliderHeight = 0,
71			showEffects = ['slideLeft', 'slideRight', 'slideUp', 'slideDown'],
72			showEffectNum = showEffects.length,
73			slides = [],
74			$newBgImage = null,
75			$oldBgImage = null,
76			defaultBg = '#252525',
77			isIe8 = PEXETO.getBrowser().msie && PEXETO.getBrowser().version<=8,
78			loadProgress = 0,
79			videoPlaying = false,
80			videoLoading = false,
81			pendingVideoFunctions = [],
82			mouseIn = false,
83			supportsTransition = PEXETO.utils.supportsTransition(),
84			isMobile = PEXETO.utils.checkIfMobile(),
85			elTiming = isMobile ? 300 : 150;
86
87		$root = $(this);
88		$parent = $root.parent();
89		$ul = $root.find(o.ulSel);
90
91		if(typeof PEXETO.videoId === 'undefined'){
92			PEXETO.videoId = 0;
93		}
94
95
96		/**
97		 * Inits the slider - calls the main functionality.
98		 */
99
100		function init() {
101
102			$root.addClass(o.loadingClass);
103
104			//get the items number
105			itemNum = $ul.find('li').each(function(i) {
106				var $li = $(this),
107					layout = $li.data('layout');
108
109
110				slides[i] = {
111					firstBox: layout === 'centered' ? $li.find(o.centerBoxSel) : $li.find(o.firstBoxSel),
112					secondBox: layout === 'centered' ? null : $li.find(o.secondBoxSel),
113					li:$li,
114					layout:layout,
115					animation:$li.data('animation')
116				};
117
118				if(o.thumbnailPreview && $li.data('thumbnail')){
119					slides[i].thumbnail = $li.data('thumbnail');
120				}
121
122				if($li.data('bg_image_url')){
123					slides[i].bgImage = $li.data('bg_image_url');
124					slides[i].bgOpacity = $li.data('bg_image_opacity');
125				}
126
127				if($li.data('bg_align')){
128					slides[i].bgAlign = $li.data('bg_align');
129				}
130
131				if($li.data('bg_style')){
132					slides[i].bgStyle = $li.data('bg_style');
133				}
134
135				if($li.data('bg_color')){
136					slides[i].bgColor = $li.data('bg_color');
137					$parent.css({backgroundColor:slides[i].bgColor});
138				}
139
140				if($li.data('video')){
141					slides[i].video = $li.data('video');
142				}
143
144			}).length;
145
146			if(!o.arrows && isMobile && itemNum>=1){
147				//show the arrows on mobile
148				o.arrows = true;
149			}
150
151			if(!o.arrows || itemNum<=1){
152				o.thumbnailPreview = false;
153			}
154
155
156
157			$.when(loadSlideImages(0,0), setSliderPadding()).done(function(){
158				doOnImgLoaded();
159				$root.removeClass(o.loadingClass);
160				showSlide(0);
161			});
162
163			if(itemNum<=1){
164				o.buttons=false;
165				o.arrows=false;
166				o.autoplay=false;
167			}
168
169			if(isMobile){
170				o.autoplay=o.autoplayMobile;
171				if(o.autoplayMobile){
172					o.pauseOnHover = false;
173				}
174			}
175
176			loadSlideImages(1,itemNum-1).done(doOnImgLoaded);
177		}
178
179		function doOnImgLoaded(){
180			loadProgress+=0.5;
181			if(loadProgress===1){
182				//both the first image and the rest of the images have been loaded
183				//init the slider functionality
184				
185				//set the navigation buttons
186				setNavigation();
187				bindEventHandlers();
188
189				if(o.thumbnailPreview){
190					setThumbnailPreviews(0);
191				}
192
193				//the images are loaded, start the animation
194				if(o.autoplay) {
195					startAnimation();
196				}
197
198			}
199		}
200
201		function loadSlideImages(firstIndex, lastIndex){
202			var deferred = new $.Deferred(),
203				progress = 0,
204				imgSrcToLoad = [],
205				imagesToLoad = [],
206				imgNum = 0,
207				imgLoaded = 0,
208				img = null,
209				i,
210				onImgLoaded = function(){
211					imgLoaded++;
212
213					if(imgLoaded===imgNum){
214						deferred.resolve();
215					}
216				};
217
218			for(i=firstIndex; i<=lastIndex; i++){
219				slides[i].li.find('img').each(function(){
220					imgSrcToLoad.push($(this).attr('src'));
221				});
222
223				if(slides[i].bgImage){
224					imgSrcToLoad.push(slides[i].bgImage);
225				}
226
227				if(o.thumbnailPreview && slides[i].thumbnail){
228					imgSrcToLoad.push(slides[i].thumbnail);
229				}
230			}
231
232			imgNum = imgSrcToLoad.length;
233
234			for(i=0; i<imgNum; i++){
235				img = new Image();
236				img.src = imgSrcToLoad[i];
237				imagesToLoad.push($(img));
238			}
239
240			if(imgNum===0){
241				deferred.resolve();
242			}else{
243				for(i=0; i<imgNum; i++){
244					imagesToLoad[i].pexetoOnImgLoaded({callback:onImgLoaded});
245				}
246			}
247
248			return deferred;
249		}
250
251		function setSliderPadding(){
252			var deferred = new $.Deferred(),
253				$logoImg;
254
255			if(isMobile || $root.parents('.content').length){
256				deferred.resolve();
257				return deferred;
258			}
259
260			$logoImg = $('#logo-container').find('img');
261
262			if($logoImg.length){
263				$logoImg.pexetoOnImgLoaded({callback:function(){
264					var logoHeight = $logoImg.height();
265					$parent.css({paddingTop:logoHeight});
266
267					deferred.resolve();
268				}});
269			}
270
271			return deferred;
272		}
273
274		/**
275		 * Binds event handlers for the main slider functionality.
276		 */
277
278		function bindEventHandlers() {
279
280			if(o.buttons) {
281				//add event handlers
282				$nav.on({
283					'click': doOnBtnClick,
284					'slideChanged': doOnSlideChanged
285				}, 'li');
286
287			}
288
289			if(o.arrows) {
290				$prevArrow.on('click', function() {
291					mouseIn = true;
292					doOnArrowClick(false);
293				});
294				$nextArrow.on('click', function() {
295					mouseIn = true;
296					doOnArrowClick(true);
297				});
298			}
299
300
301
302			//display/hide the navigation on $root hover
303			$root.on({
304				'mouseenter': doOnSliderMouseEnter,
305				'mouseleave': doOnSliderMouseLeave
306			});
307
308			$(window).on('resize', function(){
309				setSliderHeight(currentIndex);
310				centerSlide(currentIndex);
311			});
312		}
313
314		/**
315		 * Calls the functionality to change the current slide with another one.
316		 * @param  {int} index the index of the new slide
317		 */
318
319		function changeSlide(index) {
320			if(!inAnimation) {
321				inAnimation = true;
322				hideSlide(currentIndex);
323				showSlide(index);
324				currentIndex = index;
325
326				if(o.thumbnailPreview){
327					setThumbnailPreviews(index);
328				}
329
330				if(o.buttons) {
331					$navLi.trigger('slideChanged');
332				}
333			}
334		}
335
336		function setThumbnailPreviews(index){
337			var nextSlideIndex = getNextSlideIndex(index),
338				prevSlideIndex = getPrevSlideIndex(index);
339			setThumbnailPreview($nextArrow, nextSlideIndex);
340			setThumbnailPreview($prevArrow, prevSlideIndex);
341		}
342
343		function setThumbnailPreview($arrow, index){
344			var thumbnail = slides[index].thumbnail;
345			$arrow.find('.cs-thumbnail').remove();
346			
347			if(thumbnail){
348				$arrow.prepend('<img src="'+thumbnail+'" class="cs-thumbnail" />');
349			}
350		}
351
352
353		/**
354		 * Adds navigation buttons to the slider and sets event handler functions to them.
355		 */
356
357		function setNavigation() {
358			var i, html = '';
359
360			//generate the buttons
361			if(o.buttons) {
362				$nav = $('<ul />', {
363					id: o.navigationId
364				});
365				for(i = 0; i < itemNum; i++) {
366					html += '<li><span></span></li>';
367				}
368				$nav.html(html).appendTo($root).fadeIn(700);
369
370				$navLi = $nav.find('li');
371				$navLi.eq(0).addClass(o.selectedClass);
372			}
373
374			//generate the arrows
375			if(o.arrows) {
376				$prevArrow = $('<div />', {
377					'class': o.prevArrowClass
378				}).appendTo($root);
379				$nextArrow = $('<div />', {
380					'class': o.nextArrowClass
381				}).appendTo($root);
382			}
383
384		}
385
386		/***********************************************************************
387		 * EVENT HANDLER FUNCTIONS
388		 **********************************************************************/
389
390		/**
391		 * On arrow click event handler. Calls a function to change the slide
392		 * depending on which arrow (previous/next) was clicked.
393		 * @param  {boolean} next whether the next arrow is clicked (set it to true)
394		 * or the previous one was cicked (set it to false)
395		 */
396
397		function doOnArrowClick(next) {
398			var index;
399			if(next) {
400				//next index will be the next item if there is one or the first item
401				index = getNextSlideIndex(currentIndex);
402			} else {
403				//previous index will be the previous item if there is one or the last item
404				index = getPrevSlideIndex(currentIndex);
405			}
406			if(!inAnimation) {
407				pause();
408			}
409			changeSlide(index);
410		}
411
412		function getNextSlideIndex(index){
413			return index + 1 < itemNum ? index + 1 : 0;
414		}
415
416		function getPrevSlideIndex(index){
417			return index - 1 >= 0 ? index - 1 : itemNum - 1;
418		}
419
420		/**
421		 * On slider mouse enter event handler.
422		 */
423
424		function doOnSliderMouseEnter() {
425			if(o.buttons) {
426				//show the buttons
427				$nav.stop().fadeIn(function() {
428					$nav.animate({
429						opacity: 1
430					}, 0);
431				});
432			}
433
434			if(o.autoplay && o.pauseOnHover) {
435				//pause the animation
436				stopAnimation();
437				mouseIn = true;
438			}
439		}
440
441		/**
442		 * On slider mouse leave event handler.
443		 */
444
445		function doOnSliderMouseLeave() {
446			if(o.buttons) {
447				//hide the buttons
448				$nav.stop().animate({
449					opacity: 0
450				});
451			}
452
453			if(o.autoplay && o.pauseOnHover) {
454				//resume the animation
455				mouseIn = false;
456				startAnimation();
457			}
458		}
459
460		/**
461		 * On navigation button click event handler. Calls the functionality
462		 * to show the slide that corresponds to the button index.
463		 * @param  {object} e the event object
464		 */
465
466		function doOnBtnClick(e) {
467			e.stopPropagation();
468			var index = $navLi.index($(this));
469			if(!inAnimation) {
470				pause();
471			}
472			if(currentIndex !== index) {
473				changeSlide(index);
474			}
475		}
476
477		/**
478		 * On slider change event handler. Sets the current button in the navigation
479		 * to be selected according to the current slide index.
480		 */
481
482		function doOnSlideChanged() {
483			var index = $navLi.index($(this));
484			if(currentIndex === index) {
485				$(this).addClass(o.selectedClass);
486			} else {
487				$(this).removeClass(o.selectedClass);
488			}
489		}
490
491		/***************************************************************************
492		 * ANIMATION FUNCTIONS
493		 **************************************************************************/
494
495		/**
496		 * Hides a slide with a random animation.
497		 * @param {int} index the index of the slide to be displayed
498		 */
499
500		function hideSlide(index) {
501
502			var slide = slides[index],
503				$firstBox = slides[index].firstBox,
504				$secondBox = slides[index].secondBox,
505				finishHide = function($box){
506					slide.li.hide();
507					$box.find('.cs-element').removeClass('cs-animate');
508				};
509
510			if(slide.video){
511				hideVideo(slide);
512			}
513
514
515			//hide the first box
516			hideInnerElements($firstBox, function(){
517				finishHide($firstBox);
518			});
519
520			//hide the second box
521			if($secondBox){
522				hideInnerElements($secondBox, function(){
523					finishHide($secondBox);
524				});
525			}
526
527			if($newBgImage){
528				//fade out the background image
529				$oldBgImage = $newBgImage;
530				$oldBgImage.animate({opacity:0}
530, 1000, function(){
531					$(this).remove();
532					$oldBgImage = null;
533				});
534			}
535
536		}
537
538		function hideInnerElements($box, callback){
539			var $elements = $box.find('.cs-element');
540			$elements.css({opacity:0});
541			if(callback){
542				if(supportsTransition){
543					$elements.last().on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){
544						callback.call();
545						$(this).off('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd');
546					});
547				}else{
548					callback.call();
549				}
550			}
551		}
552
553		function centerSlide(index){
554			var slide = slides[index];
555
556			if(slide.layout=='centered'){
557				var liHeight = slide.li.height(),
558					ulHeight = Math.max(sliderHeight, parseInt($ul.css('minHeight'), 10));
559				if(ulHeight > liHeight){
560					slide.li.css({paddingTop:((ulHeight-liHeight)/2)});
561				}
562			}
563		}
564
565		/**
566		 * Displays a slide with a random animation.
567		 * @param {int} index the index of the slide to be displayed
568		 */
569
570		function showSlide(index) {
571			var slide = slides[index],
572				animation = slide.animation === 'random' ? 
573					showEffects[Math.floor(Math.random() * showEffectNum)] :
574					slide.animation,
575				//get a random effect
576				$firstBox = slide.firstBox,
577				$secondBox = slide.secondBox,
578				lastBox = true;
579
580
581			videoPlaying = false;
582			slide.li.show();
583
584			if(slide.video){
585				initVideo(slide);
586			}
587			
588
589			setSliderHeight(index);
590
591			centerSlide(index);
592
593
594			//show the background image
595			if(slide.bgImage){
596				var cssArgs = {backgroundImage:'url('+slide.bgImage+')'};
597				if(slide.bgAlign){
598					cssArgs.backgroundPosition = slide.bgAlign;
599				}
600
601				if(slide.bgStyle){
602					//only the default style is parallax (background-attachment fixed), the other styles are scroll
603					cssArgs.backgroundAttachment = 'scroll';
604					if(slide.bgStyle==='contain'){
605						cssArgs.backgroundSize = 'contain';
606					}
607				}
608
609				$newBgImage = $('<div />', {'class':'full-bg-image'})
610					.css(cssArgs)
611					.insertBefore($root)
612					.animate({opacity:slide.bgOpacity}, 1000);
613
614				if(isIe8){
615					new PEXETO.utils.bgCoverFallback($newBgImage).init();
616				}
617
618			}
619
620			if(slide.bgColor){
621				$parent.css({backgroundColor:'#'+slide.bgColor});
622			}else if($parent.css('backgroundColor')!==defaultBg){
623				$parent.css({backgroundColor:defaultBg});
624			}
625			
626			$.when(
627				(function(){
628					//animate the first box elements with a delay
629					var def = new $.Deferred();
630					setTimeout(function() {
631						showInnerElements($firstBox, animation, def);
632					}, o.animationSpeed / 2 + 150);
633					return def;
634				}()),
635				(function(){
636					//animate the second box elements
637					var def = new $.Deferred();
638					if($secondBox){
639						showInnerElements($secondBox, animation, def);
640					}else{
641						def.resolve();
642					}
643					return def;
644				}())
645			).done(function(){
646				setEndAnimation();
647			});
648		}
649
650		function initVideo (slide) {
651			videoLoading = true;
652			pause();
653
654			var videoElId = 'video-'+(PEXETO.videoId++),
655				initElVideo = function(){
656					var player = new YT.Player(videoElId, {
657			          height: '100%',
658			          width: '100%',
659			          videoId: slide.video,
660			          events: {
661			            'onReady': function(){
662							slide.$videoWrap
663								.animate({opacity:1}, 700)
664								.parent().removeClass('loading');
665							videoLoading = false;
666							startAnimation();
667
668							
669			            },
670			            'onStateChange': function(event){
671							if (event.data == YT.PlayerState.PLAYING) {
672								stopAnimation();
673								videoPlaying = true;
674							}
675			            }
676			          }
677			        });
678
679					PEXETO.init.ieIframeFix(); //fix the iframe z-index bug on IE
680
681				};
682
683			slide.$videoWrap = slide.li.find('.cs-video:first').css({opacity:0});
684			$('<div />', {'id':videoElId}).appendTo(slide.$videoWrap);
685			slide.$videoWrap.parent().addClass('loading');
686
687			if(window.YT && window.YT.Player){
688				initElVideo();
689			}else{
690				if(!PEXETO.pendingVideoFunctions){
691					PEXETO.pendingVideoFunctions = [];
692				}
693				PEXETO.pendingVideoFunctions.push(initElVideo);
694			}
695		}
696
697		function hideVideo(slide){
698			slide.$videoWrap.animate({opacity:0}
698, function(){
699				slide.$videoWrap.empty();
700			});
701		}
702
703		function showInnerElements($box, animation, def){
704			var i = 100,
705				settings = getPositionPropertySettings(animation),
706				animateProperty = settings.property,
707				mult = settings.mult,
708				pos = 150*mult,
709				$elements = $box.find('.cs-element');
710
711			if(!$elements.length){
712				def.resolve();
713				return;
714			}
715
716			$elements.each(function(index){
717				var $el = $(this),
718					args = {opacity:0};
719
720				if(!isMobile){
721					args[animateProperty] = pos;
722				}
723
724				$el.css(args);
725
726				setTimeout(function(){
727					var showArgs = {opacity:1},
728						args;
729					showArgs[animateProperty] = 0;
730					args = [showArgs];
731
732					if(index===$elements.length-1){
733						//add a callback function to be executed after the
734						//element animation
735						args.push(function(){
736							def.resolve();
737						});
738					}
739
740					$el.addClass('cs-animate');
741					$.fn.pexetoTransit.apply($el, args);
742					
743				}, i);
744				i+=elTiming;
745				pos = pos > 20 ? pos-20 : pos;
746			});
747		}
748
749		function getPositionPropertySettings(animation){
750			var settings = {
751				'slideLeft' : {property: 'left', mult: 1},
752				'slideRight' : {property: 'left', mult: -1},
753				'slideUp' : {property: 'top', mult: 1},
754				'slideDown' : {property: 'top', mult: -1}
755			};
756
757			return settings[animation];
758
759		}
760
761		function setSliderHeight(index){
762
763			sliderHeight = slides[index].li.height();
764
765			$ul.css({height: sliderHeight});
766		}
767
768
769		/**
770		 * Starts the animation.
771		 */
772
773		function startAnimation() {
774			if(o.autoplay && stopped && !videoPlaying) {
775				if(o.pauseOnHover && mouseIn){
776					//the mouse is still within the container
777					return;
778				}
779				stopped = false;
780				timer = window.setInterval(callNextSlide, o.animationInterval);
781			}
782		}
783
784		/**
785		 * Sets the inAnimation variable to false.
786		 */
787
788		function setEndAnimation() {
789			inAnimation = false;
790		}
791
792		/**
793		 * Triggers a changeSlide event to display the next slide.
794		 */
795
796		function callNextSlide() {
797			if(!videoLoading){
798				var nextIndex = (currentIndex < itemNum - 1) ? (currentIndex + 1) : 0;
799				changeSlide(nextIndex);
800			}
801		}
802
803		/**
804		 * Stops the animation.
805		 */
806
807		function stopAnimation() {
808			if(o.autoplay) {
809				window.clearInterval(timer);
810				timer = -1;
811				stopped = true;
812			}
813		}
814
815		/**
816		 * Pauses the animation.
817		 */
818
819		function pause() {
820			if(o.autoplay) {
821				window.clearInterval(timer);
822				timer = -1;
823				if(!stopped) {
824					window.setTimeout(startAnimation, o.pauseInterval);
825				}
826				stopped = true;
827			}
828		}
829
830
831		init();
832
833	};
834
835}(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.