PageSourceSearch

https://www.psafe.com/wp-content/themes/tonykuehn/assets/card_slider/js/jquery.cardslider.min.js

js psafe.com collected 2026-09-24 09:54:46 UTC 12,456 bytes, 438 lines download raw bytes

1;(function (factory) {
2	if(typeof module === "object" && typeof module.exports === "object") {
3		factory(require("jquery"), window, document);
4	} else {
5		factory(jQuery, window, document);
6	}
7}( function( $, window, document, undefined ) {
8
9	"use strict";
10
11	var pluginName = "cardslider",
12		defaults = {
13			keys: {
14				next: 38,
15				prev: 40
16			},
17			direction: 'down',
18			nav: true,
19			swipe: false,
20			dots: false,
21			loop: false,
22			beforeCardChange: null,
23			afterCardChange: null,
24      showCards: 0
25		};
26
27	function Plugin ( element, options ) {
28		this.element = element;
29
30    options.showCards-=1;
31
32		this.settings = $.extend( {}, defaults, options );
33		this._defaults = defaults;
34		this._name = pluginName;
35		this._cards = [];
36		this._activeCard = null;
37		this._directionClass = 'cardslider--direction-'+this.settings.direction;
38		this._animationClassBack = 'cardslider--sortback-'+this.settings.direction;
39		this._animationClassFront = 'cardslider--sortfront-'+this.settings.direction;
40		this._dotnav = null;
41		this._directionnav = null;
42		this._buttonNext = null;
43		this._buttonPrev = null;
44		this._xDown = null;
45		this._yDown = null;
46		this._swipeThreshold = 100;
47
48		this.init();
49	}
50
51	$.extend( Plugin.prototype, {
52		init: function() {
53
54			this.initCards();
55
56			if(this.settings.nav) {
57				this.initNav();
58			}
59
60			if(this.settings.dots) {
61				this.initDots();
62			}
63
64			if(this.settings.swipe) {
65				this.initSwipe();
66			}
67
68			if(this.settings.keys !== false) {
69				window.addEventListener('keydown', this.keyNav.bind(this));
70			}
71
72			this.changeCardTo(0);
73		},
74		initCards: function() {
75
76			this.element.className = this.element.className + ' cardslider ' + this._directionClass;
77
78			var list = this.element.querySelector('ul');
79			if(!list) return false;
80
81			list.classList.add('cardslider__cards');
82
83      var rawcards = list.children;
84      for(var i = 0; i < rawcards.length; i++) {
85        var rawcard = rawcards[i];
86
87        var hidden = this.settings.showCards != 0 && i > this.settings.showCards;
88
89        var card = {
90					elem: rawcard,
91					active: i === 0? true : false,
92					index: i,
93					cardClass: 'cardslider__card--index-' + i
94				};
95
96        card.elem.className = card.elem.className
97        + ' cardslider__card cardslider__card--transitions '
98        + card.cardClass
99        + (hidden && ' cardslider__card--invisible');
100
101        card.elem.style.zIndex = rawcards.length - i;
102
103				this._cards.push(card);
104      }
105		},
106		initNav: function() {
107			this._directionnav = document.createElement('div');
108			this._directionnav.className = 'cardslider__direction-nav';
109
110			this._buttonNext = document.createElement('button');
111			this._buttonNext.title = 'next';
112			this._buttonNext.className = 'cardslider__nav-next';
113			this._buttonNext.innerHTML = 'Next';
114      this._buttonNext.addEventListener('click', this.nextCard.bind(this));
115
116			this._buttonPrev = document.createElement('button');
117			this._buttonPrev.title = 'previous';
118			this._buttonPrev.className = 'cardslider__nav-prev';
119			this._buttonPrev.innerHTML = 'Prev';
120      this._buttonPrev.addEventListener('click', this.prevCard.bind(this));
121
122			this._directionnav.appendChild(this._buttonNext);
123			this._directionnav.appendChild(this._buttonPrev);
124			this.element.appendChild(this._directionnav);
125		},
126		initDots: function() {
127			var cardslider = this;
128			this._dotnav = document.createElement('ul');
129			this._dotnav.className = 'cardslider__dots-nav';
130
131			for(var i = 0; i < this._cards.length; i++) {
132				var dot = document.createElement('button');
133        dot.className = 'cardslider__dot-btn';
134				dot.setAttribute('data-slide', i);
135				dot.setAttribute('type', 'button');
136
137				dot.addEventListener('click', function(e) {
138					cardslider.changeCardTo(parseInt(e.target.getAttribute('data-slide')));
139				});
140
141				var listItem = document.createElement('li');
142				listItem.className = 'cardslider__dot';
143        listItem.appendChild(dot)
144				this._dotnav.appendChild(listItem);
145			}
146
147			this.element.appendChild(this._dotnav);
148		},
149		initSwipe: function() {
150      this.element.addEventListener('touchstart', this.handleTouchStart.bind(this), {passive:true});
151			this.element.addEventListener('touchmove', this.handleTouchEnd.bind(this), {passive:true});
152		},
153		handleTouchStart: function(e) {
154      this._xDown = e.touches[0].clientX;
155      this._yDown = e.touches[0].clientY;
156		},
157		handleTouchEnd: function(e) {
158  		e.preventDefault();
159
160      if ( ! this._xDown || ! this._yDown ) {
161        return;
162      }
163
164      var next = false;
165      var prev = false;
166
167      var xUp = e.touches[0].clientX;
168      var yUp = e.touches[0].clientY;
169
170      var xDiff = this._xDown - xUp;
171      var yDiff = this._yDown - yUp;
172
173      if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {
174
175        if(Math.abs(xDiff) < this._swipeThreshold) {return;}
176
177        if ( xDiff > 0 ) { // left swipe
178          if(this.settings.direction == 'left') {
179            next = true;
180          }
181          else if(this.settings.direction == 'right') {
182            prev = true;
183          }
184        } else { //right swipe
185          if(this.settings.direction == 'right') {
186            next = true;
187          }
188          else if(this.settings.direction == 'left') {
189            prev = true;
190          }
191        }
192      } else {
193
194        if(Math.abs(yDiff) < this._swipeThreshold) {return;}
195
196        if ( yDiff > 0 ) { //up swipe
197          if(this.settings.direction == 'up') {
198            next = true;
199          }
200          else if(this.settings.direction == 'down') {
201            prev = true;
202          }
203        } else { //down swipe
204          if(this.settings.direction == 'down') {
205            next = true;
206          }
207          else if(this.settings.direction == 'up') {
208            prev = true;
209          }
210        }
211      }
212
213      if(next) {
214        this.nextCard();
215      }
216      else if(prev) {
217        this.prevCard();
218      }
219
220      this._xDown = null;
221      this._yDown = null;
222		},
223		keyNav: function(e) {
224			if(e.keyCode == this.settings.keys.next) {
225				e.preventDefault();
226				this.nextCard();
227			}
228			else if(e.keyCode == this.settings.keys.prev) {
229				e.preventDefault();
230				this.prevCard();
231			}
232		},
233		nextCard: function() {
234			if(this._activeCard.index + 1 < this._cards.length) {
235				this.changeCardTo(this._activeCard.index + 1);
236			}
237			else if(this.settings.loop) {
238        this.changeCardTo(0, true);
239			}
240		},
241		prevCard: function() {
242			if(this._activeCard.index - 1 >= 0) {
243				this.changeCardTo(this._activeCard.index - 1);
244			}
245			else if(this.settings.loop) {
246        this.changeCardTo((this._cards.length-1)*-1);
247			}
248		},
249		changeCardTo: function(index, resetZ) {
250
251      // set param default
252      resetZ = typeof resetZ != 'undefined'? resetZ : false;
253
254      // normalize indeX
255      if(typeof index == 'string') {
256				if(index == 'first') {
257					index = 0;
258				}
259				else {
260					index = this._cards.length-1;
261				}
262			}
263
264			var indexAbs = Math.abs(index);
265
266			// set variables for easy access
267			var oldCard = this._activeCard;
268			var newCard = this._cards[indexAbs];
269
270      // remove left over animation classes
271      if(this.settings.loop) {
272        var that = this;
273        this._cards.forEach(function(card) {
274          card.elem.classList.remove(that._animationClassFront);
275  				card.elem.classList.remove(that._animationClassBack);
276  				card.elem.classList.add('cardslider__card--transitions');
277        });
278			}
279
280			// fire before callback
281			if(typeof this.settings.beforeCardChange == 'function') {
282				this.settings.beforeCardChange(oldCard.index);
283			}
284
285			if(oldCard && (index > oldCard.index || (index < oldCard.index && resetZ)) || !oldCard && index > 0) {
286				for(var i = 0; i < indexAbs; i++) {
287
288  				this._cards[i].elem.setAttribute('aria-hidden', true);
289
290					if(!this.settings.loop) {
291  				  this._cards[i].elem.classList.add('cardslider__card--out');
292  				}
293				}
294
295				if(this.settings.loop && oldCard != null) {
296          oldCard.elem.classList.remove('cardslider__card--transitions');
297          oldCard.elem.classList.add(this._animationClassBack);
298        }
299			}
300			else if(oldCard) {
301        if(this.settings.loop && oldCard) {
302          this._cards[indexAbs].elem.classList.remove('cardslider__card--transitions');
303  			  this._cards[indexAbs].elem.classList.add(this._animationClassFront);
304  			}
305        this._cards.forEach(function(card) {
306          card.elem.classList.add('cardslider__card--out');
307					card.elem.setAttribute('aria-hidden', true);
308        });
309			}
310
311      // make the front most card to the active one
312			this._activeCard = newCard;
313			this._activeCard.elem.setAttribute('aria-hidden', false);
314
315      // reorder all index classes to push the cards to their new position
316			this.reorderIndices(indexAbs);
317
318      // change the dot nav
319      if(this.settings.dots) {
320				this.changeDots(indexAbs);
321			}
322
323      // fire after callback
324      if(typeof this.settings.afterCardChange == 'function') {
325				this.settings.afterCardChange(indexAbs);
326			}
327
328			return this;
329		},
330		changeDots: function(index) {
331      var active = this._dotnav.querySelector('.cardslider__dot--active');
332      if(active) {
333        active.classList.remove('cardslider__dot--active');
334      }
335
336      var next = this._dotnav.querySelector('.cardslider__dot:nth-child('+(index+1)+')');
337      if(next) {
338        next.classList.add('cardslider__dot--active');
339      }
340		},
341		reorderIndices: function(index) {
342      var that = this;
343      var cardLen = that._cards.length - 1;
344  		this._cards.forEach(function(card, i) {
345				if(i-index >= 0) {
346  				var cardClasses = card.elem.className;
347          cardClasses = cardClasses.replace(/cardslider__card--index-\d|cardslider__card--out/g, '');
348  				card.elem.className = cardClasses.replace('  ',' ').trim();
349
350          var newCardClass = that._cards[i-index].cardClass;
351
352          card.elem.classList.add(newCardClass);
353
354          var parsed = parseInt(newCardClass.slice(-1));
355
356          if(parsed > that.settings.showCards) {
357            card.elem.classList.add('cardslider__card--invisible');
358          }
359          else {
360            card.elem.classList.remove('cardslider__card--invisible');
361          }
362
363          if(that.settings.loop) {
364					  that.setZindex(card, cardLen - that._cards[i-index].index);
365					}
366				}
367				else if(that.settings.loop) {
368  				var cardClasses = card.elem.className;
369  				cardClasses = cardClasses.replace(/cardslider__card--index-\d|cardslider__card--out/g, '');
370  				card.elem.className = cardClasses.replace('  ',' ').trim();
371          var newCardClass = that._cards[that._cards.length-(index-i)].cardClass;
372					card.elem.classList.add(newCardClass);
373
374          var parsed = parseInt(newCardClass.slice(-1));
375
376          if(parsed > that.settings.showCards) {
377            card.elem.classList.add('cardslider__card--invisible');
378          }
379          else {
380            card.elem.classList.remove('cardslider__card--invisible');
381          }
382
383					that.setZindex(card, cardLen - that._cards[that._cards.length-(index-i)].index);
384				}
385  		});
386		},
387		setZindex: function(elem, index) {
388  		elem.elem.style.zIndex = index;
389		},
390		destroy: function() {
391			var list = this.element.querySelector('.cardslider__cards');
392			this.element.className = this.element.className.replace(this.element.className.match(/card.*/g)[0], '');
393
394			list.classList.remove('cardslider__cards');
395
396			this._cards.forEach(function(card) {
397  		  card.elem.className = card.elem.className.replace(card.elem.className.match(/card.*/g)[0], '');
398  			card.elem.removeAttribute('style');
399  			card.elem.removeAttribute('aria-hidden');
400			});
401
402      if(this._dotnav) {
403		    this._dotnav.parentElement.removeChild(this._dotnav);
404		    this._dotnav = null;
405      }
406
407      if(this._directionnav) {
408			  this._directionnav.parentElement.removeChild(this._directionnav);
409			  this._directionnav = null;
410      }
411
412			this._cards = [];
413			this._activeCard = null;
414
415      if(this.settings.keys !== false) {
416			  window.removeEventListener('keydown', this.keyNav);
417      }
418
419      if(this._buttonNext) {
420			  this._buttonNext.removeEventListener('cardslider', this.nextCard);
421      }
422
423      if(this._buttonPrev) {
424			  this._buttonPrev.removeEventListener('cardslider', this.prevCard);
425      }
426
427			return this;
428		}
429	} );
430
431	$.fn[ pluginName ] = function( options ) {
432		return this.each( function() {
433			if ( !$.data( this, pluginName ) ) {
434				$.data( this, pluginName, new Plugin( this, options ) );
435			}
436		} );
437	};
438}));

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.