PageSourceSearch

https://www.therecruitability.com/wp-content/themes/recruitability/js/scripts.js?ver=v-202405012

js therecruitability.com collected 2026-09-26 08:43:21 UTC 13,679 bytes, 555 lines download raw bytes

1// vanilla js
2'use strict';
3
4let THEME_PATH = wp_helper.home_path + '/';
5
6document.addEventListener('DOMContentLoaded', () => {
7	loadFonts();
8	correctVh();
9	lazyLoad();
10	mobileMenu();
11	initTestimonialSlider();
12	initImageSlider();
13	initPostSlider();
14	initCustomSelect();
15	initAnimation();
16	initVisual();
17	initFlipNum();
18});
19
20window.addEventListener('resize', () => {
21	correctVh();
22});
23
24window.addEventListener('load', () => {
25	setTimeout(initReadMore, 300);
26});
27
28// load fonts
29function loadFonts() {
30	WebFont.load({
31		google: {
32			families: ['Montserrat:400,500,600,700'],
33		},
34		custom: {
35			families: ['Font Awesome 6 Free', 'Font Awesome 6 Brands'],
36			urls: [THEME_PATH + 'css/fonts.css'],
37		}
38	});
39}
40
41// lazyLoad Images
42function lazyLoad() {
43	const images = document.querySelectorAll('img.lazyload');
44
45	if (images.length) {
46		images.forEach(function (img) {
47			img.onload = function() {
48				img.classList.add('lazyloaded');
49
50				if (img.classList.contains('svg-html')) {
51					replaseInlineSvg(img);
52				}
53			};
54		});
55
56		window.addEventListener('load', (e) => {
57			images.forEach(img => {
58				if (img.complete && img.naturalHeight !== 0) {
59					img.classList.add('lazyloaded');
60
61					if (img.classList.contains('svg-html')) {
62						replaseInlineSvg(img);
63					}
64				}
65			});
66		});
67	}
68}
69
70// replaseInlineSvg
71function replaseInlineSvg(el) {
72	const imgID = el.getAttribute('id');
73	const imgClass = el.getAttribute('class');
74	const imgURL = el.getAttribute('src');
75
76	fetch(imgURL)
77		.then(data => data.text())
78		.then(response => {
79			const parser = new DOMParser();
80			const xmlDoc = parser.parseFromString(response, 'text/html');
81			let svg = xmlDoc.querySelector('svg');
82
83			if (typeof imgID !== 'undefined') {
84				svg.setAttribute('id', imgID);
85			}
86
87			if (typeof imgClass !== 'undefined') {
88				svg.setAttribute('class', imgClass + ' replaced-svg');
89			}
90
91			svg.removeAttribute('xmlns:a');
92
93			if (el.parentNode) {
94				el.parentNode.replaceChild(svg, el);
95			}
96	});
97}
98
99// correctVh
100function correctVh() {
101	let vh = window.innerHeight * 0.01;
102	document.documentElement.style.setProperty('--vh', vh+'px');
103}
104
105// mobile menu
106function mobileMenu() {
107	const openBtn = document.querySelector('.navbar-toggler');
108
109	if (openBtn) {
110		openBtn.addEventListener('click', function(event) {
111			event.preventDefault();
112			if ( document.body.classList.contains('menu-opened') ) {
113				document.body.classList.remove('menu-opened');
114			} else {
115				document.body.classList.add('menu-opened');
116			}
117		});
118	}
119}
120
121function initTestimonialSlider() {
122	document.querySelectorAll('.testimonial-slider').forEach(sliderEl => {
123		const swiper = new Swiper(sliderEl, {
124			loop: true,
125			slidesPerView: 1,
126			navigation: {
127				nextEl: '.swiper-button-next',
128				prevEl: '.swiper-button-prev',
129			},
130			pagination: {
131				el: '.swiper-pagination',
132				type: 'bullets',
133			},
134			breakpoints: {
135				992: {
136					slidesPerView: 2,
137				},
138			},
139		});
140	});
141}
142
143function initImageSlider() {
144	document.querySelectorAll('.image-slider').forEach(sliderEl => {
145		const swiper = new Swiper(sliderEl, {
146			loop: true,
147			autoplay: {
148				delay: 4000,
149			},
150			slidesPerView: 1,
151			navigation: {
152				nextEl: '.swiper-button-next',
153				prevEl: '.swiper-button-prev',
154			}
155		});
156	});
157}
158
159function initPostSlider() {
160	document.querySelectorAll('.post-slider').forEach(sliderEl => {
161		const swiper = new Swiper(sliderEl, {
162			loop: false,
163			slidesPerView: 1,
164			spaceBetween: 30,
165			slideVisibleClass: 'swiper-slide-visible',
166			navigation: {
167				nextEl: '.swiper-button-next',
168				prevEl: '.swiper-button-prev',
169			},
170			breakpoints: {
171				992: {
172					slidesPerView: 3,
173				},
174				768: {
175					slidesPerView: 2,
176				},
177			},
178		});
179	});
180}
181
182function initCustomSelect() {
183	const SELECTED_CLASS = 'filled';
184
185	document.querySelectorAll('select').forEach((selectEl) => {
186		const selIx = selectEl.selectedIndex;
187		let optsPlaceholder = null;
188		
189		if (selIx === 0) {
190			const selOpt = selectEl.querySelectorAll('option')[selIx];
191			optsPlaceholder = selOpt.text;
192		}
193
194		checkSelectState(selectEl);
195		selectEl.addEventListener('change', (e) => {
196			checkSelectState(selectEl);
197			window.sr.destroy('.animation-fade');
198		});
199
200		NiceSelect.bind(selectEl, {
201			// options
202			placeholder: optsPlaceholder,
203		});
204	});
205
206	function checkSelectState(selectEl) {
207		const val = selectEl.value;
208		// if (val === '-1') {
209		if (val === '') {
210			if (selectEl.classList.contains(SELECTED_CLASS)) {
211				selectEl.classList.remove(SELECTED_CLASS);
212			}
213		} else {
214			if (!selectEl.classList.contains(SELECTED_CLASS)) {
215				selectEl.classList.add(SELECTED_CLASS);
216			}
217		}
218	}
219}
220
221function initReadMore() {
222	document.querySelectorAll('.trunc-holder').forEach(truncEl => {
223		const nextEl = truncEl.nextElementSibling;
224		const moreEl = nextEl.classList.contains('trunc-more') ? nextEl : null;
225		const dot = new Dotdotdot(truncEl, {
226			ellipsis: '...',
227		});
228
229		if (moreEl) {
230			moreEl.addEventListener('click', (e) => {
231				e.preventDefault();
232				dot.API.restore();
233				moreEl.classList.add('hidden');
234			});
235		}
236	});
237}
238
239function initAnimation(selector = '') {
240	window.sr = ScrollReveal();
241	let revealSelector = '.animation-fade';
242	if (selector != '' && document.querySelector(selector)) {
243		revealSelector = selector+' '+revealSelector;
244	}
245	sr.reveal(revealSelector, {
246		scale: 1,
247		reset: false,
248		mobile: true,
249		duration: 2500,
250		distance: '0px',
251		origin: 'bottom'
252	});
253}
254
255function initVisual() {
256	document.querySelectorAll('.visual h1, .visual .h1').forEach(headEl => {
257		const headContent = headEl.innerHTML;
258		headEl.innerHTML = '';
259
260		const textEl = headEl.closest('.visual').querySelector('p');
261		let textContent;
262
263		if (textEl) {
264			textContent = textEl.innerHTML;
265			textEl.innerHTML = '';
266		}
267
268		const typed = new Typed(headEl, {
269			stringsElement: null,
270			strings: [headContent],
271			typeSpeed: 50,
272			backSpeed: 0,
273			backDelay: 500,
274			startDelay: 1000,
275			loop: false,
276			showCursor: false,
277			onComplete: function(self) {
278				headEl.classList.add('anim-finished');
279
280				if (textEl) {
281					new Typed(textEl, {
282						stringsElement: null,
283						strings: [textContent],
284						typeSpeed: 50,
285						backSpeed: 0,
286						backDelay: 500,
287						startDelay: 1000,
288						loop: false,
289						showCursor: false,
290						onComplete: function(self) {
291							textEl.classList.add('anim-finished');
292						},
293						onBegin: function(self) {
294							textEl.classList.add('anim-started');
295						},
296					});
297				}
298			},
299		});
300	})
301}
302
303function initFlipNum() {
304	document.querySelectorAll('.flip-num').forEach(counter => {
305		counter.innerText = '0' //set default counter value
306    counter.dataset.count = 0;
307
308    const updateCounter = () => {
309      const target = +counter.getAttribute('data-target').replace(',', ''); //define increase couter to it's data-target
310      const count = +counter.dataset.count; //define increase couter on innerText
311      const increment = target / 200; // define increment as counter increase value / speed
312
313			counter.classList.add('num-started');
314      if (count < target) {
315        const newCount = Math.ceil(count + increment);
316        counter.dataset.count = newCount;
317        counter.innerText = numberWithCommas(newCount);
318        setTimeout(updateCounter, 1);
319      } else {
320        counter.innerText = numberWithCommas(target); //if default value is bigger that date-target, show data-target
321      }
322    }
323
324		check();
325		window.addEventListener('scroll', check);
326		window.addEventListener('resize', check);
327
328		function check() {
329			if (isElementInViewport(counter) && !counter.classList.contains('num-started')) {
330				updateCounter();
331			}
332		}
333	});
334
335	function numberWithCommas(x) {
336    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
337  }
338
339	
340}
341
342function isElementInViewport(el, horK, vertK) {
343	horK = horK || 0.75;
344	vertK = vertK || 0.5;
345	var rect = el.getBoundingClientRect();
346	var windowHeight = (window.innerHeight || document.documentElement.clientHeight);
347	var windowWidth = (window.innerWidth || document.documentElement.clientWidth);
348	var vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0) && ((rect.top + rect.height * vertK) <= windowHeight);
349	var horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0) && ((rect.left + rect.width * horK) <= windowWidth);
350
351	return (vertInView && horInView);
352}
353
354// jQuery
355(function($){
356	
357	$(document).ready(function() {
358		$('.wpcf7-submit').addClass('btn btn-sm btn-secondary');
359		initSidebarStick();
360		
361		// Hubspot forms in modals
362		$('.modal.has-hubspot').each( function() {
363			
364			var $this = $(this),
365				modal_id = $this.attr('id'),
366				hubspot_id = $this.find('[data-hubspot-form-id]').attr('data-hubspot-form-id');
367				
368			var modal_el = document.getElementById(modal_id);
369			modal_el.addEventListener('show.bs.modal', function (event) {
370				
371				hbspt.forms.create({
372					region: "na1",
373					portalId: "22238080",
374					target: '#'+modal_id+' .hubspot-form',
375					formId: "a1967355-a05c-4359-a39b-1c59f28d5b39"
376				});
377			});
378			
379		});
380		
381	}); // ready
382
383	$(window).on('resize', function() {
384		initSidebarStick();	
385	}); // resize
386
387	$(window).on('load', function() {
388	}); // load
389	
390	/* ------------------------------------------------- */
391	/* Refresh Jobs */
392		
393		$(document).on('click', '.refresh-jobs', function(e) {
394			
395			e.preventDefault();
396			
397			var $button = $(this);
398			
399			/* Loading */
400			function do_loading() {
401				
402				$button.addClass('loading');
403				
404			}
405			
406			/* Loaded */
407			function do_loaded() {
408				
409				$button.removeClass('loading');
410				setTimeout( function() {
411					location.reload();
412				}, 1000);
413				
414			}
415			
416			/* Get Lisings */
417			$.ajax({
418				url: wp_helper.ajax_url,
419				type: 'POST',
420				data: {
421					action: 'refresh_jobs'
422				},
423				dataType: "json",
424				beforeSend:function(xhr) {
425					
426					do_loading();
427					
428				},
429				success:function(data) {
430					
431					do_loaded();
432					
433				}
434			});
435			
436		});
437		
438	/* ------------------------------------------------- */
439	/* Sidebar Stick */
440		
441		function initSidebarStick() {
442			
443			$('.sidebar.stick-it .sidebar-inner').each( function() {
444				
445				var $this			= $(this),
446					window_width 	= $(window).width(),
447					$header_bar		= $('#header'),
448					sidebarHeight 	= $this.height();
449					
450				if ( window_width > 991 ) {
451				
452					var offset_top = $header_bar.outerHeight() + 30;
453					
454					$this.stick_in_parent({
455						offset_top: offset_top,
456						parent: '.sidebar'
457					});
458					
459				}
460				
461			});
462			
463		}
464
465	// jQuery functions
466})(this.jQuery);
467
468/* ------------------------------------------------- */
469/* iFrame Videos */
470	
471	document.addEventListener('DOMContentLoaded', function () {
472	
473	// Sizing
474		const wrapper = document.querySelector('.iframe-video-wrapper');
475		if (wrapper) {
476			const iframe = wrapper.querySelector('iframe');
477			const videoAspectRatio = 16 / 9;
478			function resizeIframe() {
479				const wrapperWidth = wrapper.offsetWidth;
480				const wrapperHeight = wrapper.offsetHeight;
481				const wrapperAspectRatio = wrapperWidth / wrapperHeight;
482				let newWidth, newHeight;
483				if (wrapperAspectRatio < videoAspectRatio) {
484					// Wrapper is wider than video: scale by height
485					newHeight = wrapperHeight;
486					newWidth = newHeight * videoAspectRatio;
487				} else {
488					// Wrapper is taller than video: scale by width
489					newWidth = wrapperWidth;
490					newHeight = newWidth / videoAspectRatio;
491				}
492				if (iframe) {
493					iframe.style.width = `${newWidth}px`;
494					iframe.style.height = `${newHeight}px`;
495					iframe.style.top = `${(wrapperHeight - newHeight) / 2}px`;
496					iframe.style.left = `${(wrapperWidth - newWidth) / 2}px`;
497				}
498			}
499			resizeIframe();
500			window.addEventListener('resize', resizeIframe);
501		}
502		
503	// Play/Pause
504		const wrappers = document.querySelectorAll('.iframe-video-wrapper');
505		wrappers.forEach(wrapper => {
506			const iframe = wrapper.querySelector('iframe');
507			const button = wrapper.querySelector('.play-button');
508			
509			if (!iframe) return;
510		
511			const player = new Vimeo.Player(iframe);
512			let isPlaying = false;
513		
514			// Wait for player to be fully ready
515			player.ready().then(() => {
516				console.log('✅ Vimeo player ready');
517				wrapper.classList.add('ready');
518				
519				// Initial muted state (safer)
520				player.setMuted(true).catch(() => {});
521			}).catch(err => {
522				console.error('Player init failed:', err);
523			});
524		
525			button.addEventListener('click', () => {
526				if (!isPlaying) {
527					player.ready().then(() => {
528						// CRITICAL: Unmute + set volume INSIDE the user click gesture
529						return Promise.all([
530							player.setMuted(false),
531							player.setVolume(1.0)
532						]);
533					}).then(() => {
534						return player.play();
535					}).then(() => {
536						isPlaying = true;
537						wrapper.classList.add('playing');
538						wrapper.classList.remove('paused');
539						console.log('▶️ Playing with sound');
540					}).catch(err => {
541						console.error('Play failed:', err);
542					});
543				} else {
544					player.pause().then(() => {
545						isPlaying = false;
546						wrapper.classList.add('paused');
547						wrapper.classList.remove('playing');
548					}).catch(err => {
549						console.error('Pause failed:', err);
550					});
551				}
552			});
553		});
554	
555	});

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.