File: D:/HostingSpaces/SBogers10/lc-hydraulics.komma.nl/wwwroot/js/site/app.js
/* ==========================================================================
Browser Handler
========================================================================== */
var BrowserHandler = {
userAgent: '',
browserInfo: '',
init: function init() {
BrowserHandler.userAgent = window.navigator.userAgent;
BrowserHandler.browserInfo = BrowserHandler.getBrowserInfo();
BrowserHandler.handleIE();
BrowserHandler.handleSafari();
},
handleIE: function handleIE() {
// Detect versions below ie11
var msie = BrowserHandler.userAgent.indexOf('MSIE ');
var ielt11 = msie > 0; // Detect ie11
var ie11 = !!navigator.userAgent.match(/Trident.*rv\:11\./); // If Internet Explorer
if (ielt11 || ie11) {
// Default version
var version = '11'; // Way to detect version < 11
if (ielt11) {
version = parseInt(BrowserHandler.userAgent.substring(msie + 5, BrowserHandler.userAgent.indexOf(".", msie)));
}
var versionNumber = 'v' + version; // Append classes to HTML
document.body.classList.add('ie');
document.body.classList.add(versionNumber);
}
},
// Fallback for older safari version
handleSafari: function handleSafari() {
if (BrowserHandler.browserInfo.name === 'Safari' && BrowserHandler.browserInfo.version <= 10) $('html').addClass('ie');
},
getBrowserInfo: function getBrowserInfo() {
var ua = navigator.userAgent,
tem,
M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
if (/trident/i.test(M[1])) {
tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
return {
name: 'IE ',
version: tem[1] || ''
};
}
if (M[1] === 'Chrome') {
tem = ua.match(/\bOPR\/(\d+)/);
if (tem != null) {
return {
name: 'Opera',
version: tem[1]
};
}
}
M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
if ((tem = ua.match(/version\/(\d+)/i)) != null) {
M.splice(1, 1, tem[1]);
}
return {
name: M[0],
version: M[1]
};
}
};
BrowserHandler.init();
/* ==========================================================================
| Prevent Bots handler
|
| We named this chocolate factory and belonging confusing js hooks
| to prevent smart bots from blocking these variable or functions.
|
========================================================================== */
var ChocolateFactory = {
bannedVisitor: [],
/** Get all the chocolate factory and start
* Looping through those start flashing tickets
*/
enter: function enter() {
var chocolateFactories = document.querySelectorAll('.js-chocolate-factory');
if (isset(chocolateFactories)) {
var amountOfChocolateFactories = chocolateFactories.length;
for (var i = 0; i < amountOfChocolateFactories; i++) {
var ChocolateBar = chocolateFactories[i];
ChocolateFactory._flashTicket(ChocolateBar);
}
}
},
/**
* If factory has a golden ticket
* Then we can make them go on the tour if there has been click on the ticket
*
* @param chocolateBar
* @private
*/
_flashTicket: function _flashTicket(chocolateBar) {
// Try get the ticket from the chocolateBar
var goldenTicket = chocolateBar.querySelector('.js-golden-ticket'); // Only continue if chocolate bar has a golden ticket
if (isset(goldenTicket)) {
goldenTicket.addEventListener('click', function () {
ChocolateFactory.enjoyTheTour(chocolateBar);
});
} else {
console.log('To bad, no golden tickets has been found.');
}
},
/**
* Start the tour through the factory
* And get the names and properties of the members of the group
* If there are members in the group of course
*
* @param chocolateFactory
*/
enjoyTheTour: function enjoyTheTour(chocolateFactory) {
// Ask for the tour group
var tourGroup = chocolateFactory.querySelectorAll('input, textarea');
if (isset(tourGroup)) {
// For each visitor we want a belonging Oompa Loompa
var oompaLoompas = {};
var amountOfOompaLoompas = 0;
var tourGroupSize = tourGroup.length;
for (var i = 0; i < tourGroupSize; i++) {
// Get the visitor from the group
var visitor = tourGroup[i]; // Ask for its name
var visitorName = visitor.getAttribute('name'); // Check if the visitor is banned
if (ChocolateFactory._isVisitorBanned(visitorName)) continue;
oompaLoompas[visitorName] = ChocolateFactory._getArrangement(visitor);
amountOfOompaLoompas++;
} // Check for insurance that there are oompa loompas
if (amountOfOompaLoompas === 0) return; // Send submit request
ChocolateFactory._finishTour(oompaLoompas, chocolateFactory);
} else {
console.log('To bad, no members to visit this factory');
}
},
/**
* Check if the visitor name isn't allow
*
* @param visitorName
* @returns {boolean}
* @private
*/
_isVisitorBanned: function _isVisitorBanned(visitorName) {
if (ChocolateFactory.bannedVisitor.indexOf(visitorName) !== -1) {
return true;
}
return false;
},
/**
* Most get visitor have a normal arrangement
* But sometimes there are special cases
* Like a Selector or checkbox
*
* @param visitor
* @returns {*}
* @private
*/
_getArrangement: function _getArrangement(visitor) {
var visitorType = visitor.nodeName;
switch (visitorType) {
default:
return visitor.value;
}
},
/**
* Finish the tour
* If successful show thanks message
* Or show defined error message or fallback
*
* @param group
* @param chocolateFactory
* @returns {*|void}
* @private
*/
_finishTour: function _finishTour(group, chocolateFactory) {
group = ChocolateFactory._addWillieWonka(group);
try {
Ajax.post('/contact/process-new', group, function (response) {
var responseData = JSON.parse(response.response);
switch (responseData.status) {
case 200:
return ChocolateFactory._thanksForVisiting(responseData.data.redirectUrl);
case 422:
return ChocolateFactory._giveFeedbackToMembers(responseData.errors, chocolateFactory);
default:
break;
}
return ChocolateFactory._unknownGapInFactory(chocolateFactory);
});
} catch (e) {
return ChocolateFactory._unknownGapInFactory(chocolateFactory);
}
},
/**
* Add willie wonka to the group
* Ps... it actually the secret code!
*
* @param group
* @returns {*}
* @private
*/
_addWillieWonka: function _addWillieWonka(group) {
group.willie = 'wonka';
return group;
},
/**
* Add the feedback to the desired area.
* Most likely to the visitor directly, but sometime to the factory desired feedback area
*
* @param errors
* @param chocolateFactory
* @private
*/
_giveFeedbackToMembers: function _giveFeedbackToMembers(errors, chocolateFactory) {
// Grab the factory feedback area
var feedbackArea = chocolateFactory.querySelector('.js-error-area'); // Clear the current html
feedbackArea.innerHTML = ''; // Clear the previous marked jackets
ChocolateFactory._clearPreviousMarkedJackets(chocolateFactory);
Object.keys(errors).forEach(function (visitor) {
console.log(visitor); // Grab the visitor feedback area
var visitorNode = chocolateFactory.querySelector('#' + visitor); // Grab the jacket of a visitor
var jacket = ChocolateFactory._grabVisitorJacket(visitorNode); // Get the feedback for this visitor
var visitorFeedback = errors[visitor]; // Spit out each line
var visitorFeedbackAmount = visitorFeedback.length;
for (var i = 0; i < visitorFeedbackAmount; i++) {
var visitorFeedbackLine = visitorFeedback[i]; // Append the feedback to the desired area
var currentFeedbackArea = feedbackArea.innerHTML;
currentFeedbackArea += '<span>' + visitorFeedbackLine + '</span>';
feedbackArea.innerHTML = currentFeedbackArea; // Only continue if jacket isset
if (visitor !== 'honey') {
// Grab the jacket of a visitor
var _jacket = ChocolateFactory._grabVisitorJacket(visitorNode); // Mark the jacket
_jacket.classList.add('has-error');
}
}
});
},
/**
* Clear the previous marked jackets
*
* @param chocolateFactory
* @private
*/
_clearPreviousMarkedJackets: function _clearPreviousMarkedJackets(chocolateFactory) {
var markedJackets = chocolateFactory.querySelectorAll('.has-error');
var markedJacketsAmount = markedJackets.length;
for (var i = 0; i < markedJacketsAmount; i++) {
markedJackets[i].classList.remove('has-error');
}
},
/**
* Grab the jacket of the visitor
*
* @param visitor
* @returns {(() => (Node | null)) | ActiveX.IXMLDOMNode | (Node & ParentNode)}
* @private
*/
_grabVisitorJacket: function _grabVisitorJacket(visitor) {
// Check if visitor is defined
if (!isset(visitor)) return null; // Do loop settings
currentLayer = visitor;
isJacket = false;
safetyBreak = 0; // Grab the next layer till it is the jacket (or safetyBreak has been reached
do {
currentLayer = currentLayer.parentNode;
if (currentLayer.classList.contains('form-element')) isJacket = true;
} while (isJacket === false || safetyBreak >= 10);
return currentLayer;
},
/**
* Redirect the visitor to the thanks page
*
* @param nextStop
* @private
*/
_thanksForVisiting: function _thanksForVisiting(nextStop) {
window.location = nextStop;
},
/**
* Unknown error occurred, log the error
*
* @param chocolateFactory
* @private
*/
_unknownGapInFactory: function _unknownGapInFactory(chocolateFactory) {
console.log(chocolateFactory);
console.log('ChocolateFactory: Unkown Error');
}
};
ChocolateFactory.enter();
/* ==========================================================================
Cookie handler
- Primary usage for toggling the cookie message and/or switch
========================================================================== */
var CookieHandler = {
cookieMessage: null,
cookieSwitch: null,
cookieFadeOutAnimationDuration: 400,
acceptTracking: false,
// Initialize cookie handler
init: function init() {
// Bind cookie message without tracking to Handler
CookieHandler.cookieMessage = document.getElementById('cookie-message'); // If isset init the functions for cookie message without tracking
if (isset(CookieHandler.cookieMessage)) {
CookieHandler.initCookieMessageWithoutTracking();
} else {
// Else try to connect cookie message with tracking to Handler
CookieHandler.cookieMessage = document.getElementById('cookie-message-overlay'); // If isset init the functions for cookie message with tracking
if (isset(CookieHandler.cookieMessage)) {
CookieHandler.initCookieMessageWithTracking();
}
} // If either type of cookie has been found check if settings are defined
if (isset(CookieHandler.cookieMessage)) {
CookieHandler.checkForCookieSettings();
} // Bind cookie switch to Handler
CookieHandler.cookieSwitch = document.getElementById('cookie-switch'); // If isset init the functions for cookie switch
if (isset(CookieHandler.cookieSwitch)) {
CookieHandler.initCookieSwitch();
}
},
// Init the cookie message actions without tracking
initCookieMessageWithoutTracking: function initCookieMessageWithoutTracking() {
var closeButton = CookieHandler.cookieMessage.querySelector('.close-button');
if (isset(closeButton)) {
closeButton.addEventListener('click', CookieHandler.closeCookieMessage);
}
},
// Init the cookie message actions with tracking
initCookieMessageWithTracking: function initCookieMessageWithTracking() {
// Open the cookie settings event
var openCookieSettingsButton = CookieHandler.cookieMessage.querySelector('.open-menu');
if (isset(openCookieSettingsButton)) {
openCookieSettingsButton.addEventListener('click', CookieHandler.openCookieSettings);
} // Toggle of the tracking input
var toggleTrackingInputWrapper = CookieHandler.cookieMessage.querySelector('#cookie-settings-menu #trackingCookie');
if (isset(toggleTrackingInputWrapper)) {
var toggleTrackingInput = toggleTrackingInputWrapper.querySelector('input');
toggleTrackingInput.addEventListener('change', CookieHandler.toggleTrackingSetting);
if (toggleTrackingInput.checked === true) {
CookieHandler.acceptTracking = true;
}
} // Accept / Save cookies button event
var acceptButton = CookieHandler.cookieMessage.querySelector('.accept-cookie-button');
if (isset(acceptButton)) {
acceptButton.addEventListener('click', CookieHandler.setCookieSettings);
}
},
// Init the cookie switch actions
initCookieSwitch: function initCookieSwitch() {
// Toggle of the tracking input
var toggleTrackingInputWrapper = CookieHandler.cookieSwitch.querySelector('#trackingCookie');
if (isset(toggleTrackingInputWrapper)) {
var toggleTrackingInput = toggleTrackingInputWrapper.querySelector('input');
toggleTrackingInput.addEventListener('change', CookieHandler.toggleTrackingSetting); // Force the state of the cookie switch input because the pop-up is forced on checked
// while the switch checks by php if the cookie really exist or not
if (toggleTrackingInput.checked === true) {
CookieHandler.acceptTracking = true;
} else {
CookieHandler.acceptTracking = false;
}
} // Save cookies button event
var saveButton = CookieHandler.cookieSwitch.querySelector('#save-cookie-settings');
if (isset(saveButton)) {
saveButton.addEventListener('click', function () {
CookieHandler.cookieFadeOutAnimationDuration = 0; // On the switch click we want no delay :)
CookieHandler.setCookieSettings();
});
}
},
checkForCookieSettings: function checkForCookieSettings() {
if (Cookie.get('cookieMessage')) {
CookieHandler.cookieMessage.classList.add('accepted');
} else {
CookieHandler.cookieMessage.classList.remove('accepted');
}
},
closeCookieMessage: function closeCookieMessage() {
Cookie.set('cookieMessage', true, 90);
CookieHandler.cookieMessage.classList.add('transition-out');
},
openCookieSettings: function openCookieSettings() {
CookieHandler.cookieMessage.querySelector('#cookie-settings-menu').classList.add('edit');
CookieHandler.cookieMessage.querySelector('#message-description').classList.add('hide');
},
toggleTrackingSetting: function toggleTrackingSetting() {
if (CookieHandler.acceptTracking) {
CookieHandler.acceptTracking = false;
} else {
CookieHandler.acceptTracking = true;
}
},
setCookieSettings: function setCookieSettings() {
// Set tracking cookie or delete it if isset according to the desired settings
if (CookieHandler.acceptTracking) {
Cookie.set('trackingCookieAccepted', 'true', 90);
} else {
if (Cookie.get('trackingCookieAccepted')) {
Cookie.erase('trackingCookieAccepted');
}
}
CookieHandler.closeCookieMessage(); // Reload after animation to automatically trigger the tracking after accepting it
setTimeout(function () {
location.reload();
}, CookieHandler.cookieFadeOutAnimationDuration);
}
};
CookieHandler.init();
/**
* Created by Pascal on 23/11/17.
*/
/**
*
* @param {string} id - html id of form
* @param {array} required - list of required field
* @constructor
*/
function FormHandler(id, required) {
// Define form object
this.formObject = document.getElementById(id); // Set required fields
this.requiredFields = required; // Set default valid to true
this.valid = true; // Validate form function
this.validate = function () {
// Reset valid to true
this.valid = true; // Define this to self
var self = this;
var fieldToValidate = self.requiredFields.slice(); // Get all form elements
var formElements = this.formObject.querySelectorAll('input, textarea'); // Loop through the form elements
var formElementsLength = formElements.length;
for (var i = 0; i < formElementsLength; i++) {
var el = formElements[i]; // Remove alert
el.classList.remove('alert');
var indexOfValidator = fieldToValidate.indexOf(el.getAttribute('name')); // Check if it's in the required fields
if (indexOfValidator !== -1) {
// Temporary store the value (for future checks or so ex. check if mail)
var value = el.value; // Check if value is filled
if (value === null || value === '') {
// Else set alert and set form valid to false
el.classList.add('alert');
self.valid = false;
} // Remove from fields to validate array
fieldToValidate.splice(indexOfValidator, 1);
}
} // Check if all required fields are filled
if (fieldToValidate.length !== 0) {
// Else also set form valid to false
// And log because it should only happen in development
self.valid = false;
console.log('Not all required field are filled:');
console.log(fieldToValidate);
}
}; // Send form
this.send = function () {
this.formObject.submit();
};
}
/* ==========================================================================
Image related javascript
========================================================================== */
/**
* Preload images
*/
var ImagePreloader = {
// Init preloader
init: function init() {
$('img.preload').one('load', function () {
// Once loaded remove the preload class
// Our CSS will take care of the fade in
$(this).removeClass('preload');
}).each(function () {
if (this.complete) $(this).load();
});
}
};
/* ==========================================================================
Google Maps handler
-- https://developers.google.com/maps/documentation/javascript/adding-a-google-map
========================================================================== */
var MapsHandler = {
map: '',
key: 'AIzaSyCGkkRN14aGn43RzCLsFt9FO9xORZIenJ8',
//Anvil
// key: 'AIzaSyB4J3vU0MbOpIRmnMk1HyKwwgU-z1HzuwM', //Lacom
location: {
lat: 51.2618222,
lng: 5.5965538
},
styling: '',
init: function init() {
// Get map by id
MapsHandler.map = document.getElementById('map'); // Check if a map is defined
if (isset(MapsHandler.map)) {
if (MapsHandler.map.hasAttribute('data-google-x')) MapsHandler.location.lat = parseFloat(MapsHandler.map.getAttribute('data-google-x'));
if (MapsHandler.map.hasAttribute('data-google-y')) MapsHandler.location.lng = parseFloat(MapsHandler.map.getAttribute('data-google-y'));
MapsHandler.setCustomStyling(); // See if google variable exists
if (typeof google == 'undefined' || typeof google.maps == 'undefined') {
// Load external script
$.getScript('https://maps.googleapis.com/maps/api/js?key=' + MapsHandler.key).done(function (script, textStatus) {
MapsHandler.drawMap();
});
} else {
MapsHandler.drawMap();
}
}
},
drawMap: function drawMap() {
// Create a map
var map = new google.maps.Map(MapsHandler.map, {
zoom: 14,
center: MapsHandler.location,
disableDefaultUI: true,
styles: MapsHandler.styling
}); // Add a marker
var marker = new google.maps.Marker({
position: MapsHandler.location,
map: map
});
},
setCustomStyling: function setCustomStyling() {
MapsHandler.styling = [{
"featureType": "poi",
"elementType": "labels.text.fill",
"stylers": [{
"color": "#747474"
}, {
"lightness": "23"
}]
}, {
"featureType": "poi.attraction",
"elementType": "geometry.fill",
"stylers": [{
"color": "#f38eb0"
}]
}, {
"featureType": "poi.government",
"elementType": "geometry.fill",
"stylers": [{
"color": "#ced7db"
}]
}, {
"featureType": "poi.medical",
"elementType": "geometry.fill",
"stylers": [{
"color": "#ffa5a8"
}]
}, {
"featureType": "poi.park",
"elementType": "geometry.fill",
"stylers": [{
"color": "#c7e5c8"
}]
}, {
"featureType": "poi.place_of_worship",
"elementType": "geometry.fill",
"stylers": [{
"color": "#d6cbc7"
}]
}, {
"featureType": "poi.school",
"elementType": "geometry.fill",
"stylers": [{
"color": "#c4c9e8"
}]
}, {
"featureType": "poi.sports_complex",
"elementType": "geometry.fill",
"stylers": [{
"color": "#b1eaf1"
}]
}, {
"featureType": "road",
"elementType": "geometry",
"stylers": [{
"lightness": "100"
}]
}, {
"featureType": "road",
"elementType": "labels",
"stylers": [{
"visibility": "off"
}, {
"lightness": "100"
}]
}, {
"featureType": "road.highway",
"elementType": "geometry.fill",
"stylers": [{
"color": "#ffd4a5"
}]
}, {
"featureType": "road.arterial",
"elementType": "geometry.fill",
"stylers": [{
"color": "#ffe9d2"
}]
}, {
"featureType": "road.local",
"elementType": "all",
"stylers": [{
"visibility": "simplified"
}]
}, {
"featureType": "road.local",
"elementType": "geometry.fill",
"stylers": [{
"weight": "3.00"
}]
}, {
"featureType": "road.local",
"elementType": "geometry.stroke",
"stylers": [{
"weight": "0.30"
}]
}, {
"featureType": "road.local",
"elementType": "labels.text",
"stylers": [{
"visibility": "on"
}]
}, {
"featureType": "road.local",
"elementType": "labels.text.fill",
"stylers": [{
"color": "#747474"
}, {
"lightness": "36"
}]
}, {
"featureType": "road.local",
"elementType": "labels.text.stroke",
"stylers": [{
"color": "#e9e5dc"
}, {
"lightness": "30"
}]
}, {
"featureType": "transit.line",
"elementType": "geometry",
"stylers": [{
"visibility": "on"
}, {
"lightness": "100"
}]
}, {
"featureType": "water",
"elementType": "all",
"stylers": [{
"color": "#d2e7f7"
}]
}];
}
};
MapsHandler.init();
/* ==========================================================================
NavigationHandler handler
========================================================================== */
/**
* Navigation Handler
* Primary usage for mobile NavigationHandler
* Secondary if site used a pop-up/slide-in menu
*/
var NavigationHandler = {
navElement: '',
navBar: '',
scrolled: 0,
isActive: false,
// Initialize click event
init: function init() {
// Bind Navigation to Handler
NavigationHandler.navElement = document.getElementById('navigation');
NavigationHandler.navBar = document.querySelector('body>header'); // Bind clicks to menu button
var menuButton = document.getElementById('menu-trigger');
if (isset(menuButton)) {
menuButton.addEventListener('click', function () {
NavigationHandler.toggle();
});
}
var mobileShade = document.getElementById('mobile-shader');
if (isset(mobileShade)) {
mobileShade.addEventListener('click', function () {
NavigationHandler.close();
});
}
var mobileClose = document.getElementById('mobile-close');
if (isset(mobileClose)) {
mobileClose.addEventListener('click', function () {
NavigationHandler.close();
});
}
if (isset(NavigationHandler.navElement)) {
setTimeout(function () {
NavigationHandler.navElement.classList.add('allow-animation');
}, 1000);
}
},
// Toggle navigation
toggle: function toggle() {
if (!NavigationHandler.isActive) NavigationHandler.open();else NavigationHandler.close();
},
// Open Navigation
open: function open() {
NavigationHandler.scrolled = window.pageYOffset;
NavigationHandler.navElement.classList.add('active');
NavigationHandler.navElement.classList.add('shader-active');
NavigationHandler.isActive = true;
if (isset(NavigationHandler.navBar)) {
NavigationHandler.navBar.classList.add('menu-active');
}
setTimeout(function () {
document.body.classList.add('preventScroll');
}, 600);
},
// Close Navigation
close: function close() {
NavigationHandler.navElement.classList.remove('active');
NavigationHandler.navElement.classList.remove('shader-active');
NavigationHandler.isActive = false;
if (isset(NavigationHandler.navBar)) {
NavigationHandler.navBar.classList.remove('menu-active');
}
document.body.classList.remove('preventScroll');
window.scrollTo(0, NavigationHandler.scrolled);
}
};
NavigationHandler.init();
/* ==========================================================================
Resize handler
========================================================================== */
/**
* Handler the objects which are or need to be recalculated on resize
*/
var ResizeHandler = {
time: Date.now(),
timeout: null,
waitThrottle: 1000,
waitDebounce: 500,
//Initialisation
init: function init() {
// Trigger start up resizes
ResizeHandler.triggerOnInit(); // Throttle Resize
window.addEventListener('resize', function () {
if (ResizeHandler.time + ResizeHandler.waitThrottle - Date.now() < 0) {
ResizeHandler.triggerThrottle();
ResizeHandler.time = Date.now();
}
}); // Smooth Resize
window.addEventListener('resize', function () {
ResizeHandler.triggerSmooth();
}); // Debounce Resize
window.addEventListener('resize', function () {
if (isset(ResizeHandler.timeout)) clearTimeout(ResizeHandler.timeout);
ResizeHandler.timeout = setTimeout(ResizeHandler.triggerDebounce, ResizeHandler.waitDebounce);
});
},
// Trigger on start up
// All function should be in here
triggerOnInit: function triggerOnInit() {// ResizeHandler.resizeWhatDoesItCostAdvantageFigure();
// console.log('Initial Resize');
},
// Trigger resize functions with throttle (preferred)
triggerThrottle: function triggerThrottle() {// console.log('Throttled Resize');
},
// Trigger resize on debounce
triggerDebounce: function triggerDebounce() {// console.log('Debounce Resize');
// ResizeHandler.resizeWhatDoesItCostAdvantageFigure();
},
// Trigger resize on the flight
triggerSmooth: function triggerSmooth() {// console.log('Smooth Resize');
} // ------------------------------ CUSTOM SCROLL HANDLERS ------------------------------------
// Example function
// resizeWhatDoesItCostAdvantageFigure: function () {
// var el = document.querySelector('.advantages-own-guiding-row figure');
// if(isset(el)){
// el.style.maxHeight = 'none';
// el.style.maxHeight = el.offsetHeight + 'px';
// }
// },
};
ResizeHandler.init();
/* ==========================================================================
Scroll handler
========================================================================== */
/**
* Handler the objects which are bind on scroll events or visible in viewport
*/
var ScrollHandler = {
// Variables for debounce and throttle effects
time: Date.now(),
timeout: null,
waitThrottle: 1000,
waitDebounce: 300,
// Variables for scroll direction
lastScrollTopPosition: 0,
scrollDirectionDown: true,
scrollDirectionUp: false,
//Initialisation
init: function init() {
// Trigger start on start up
ScrollHandler.triggerOnInit(); // Throttle scroll
window.addEventListener('scroll', function () {
if (ScrollHandler.time + ScrollHandler.waitThrottle - Date.now() < 0) {
ScrollHandler.triggerThrottle();
ScrollHandler.time = Date.now();
}
}); // Smooth scroll
window.addEventListener('scroll', function () {
ScrollHandler.triggerSmooth();
}); // Debounce scroll
window.addEventListener('scroll', function () {
if (isset(ScrollHandler.timeout)) clearTimeout(ScrollHandler.timeout);
ScrollHandler.timeout = setTimeout(ScrollHandler.triggerDebounce, ScrollHandler.waitDebounce);
});
},
// Trigger on start up
triggerOnInit: function triggerOnInit() {
ScrollHandler.triggerElementInViewportAnimation();
},
// Trigger scroll functions with throttle (preferred)
triggerThrottle: function triggerThrottle() {
// console.log('Throttled scroll');
ScrollHandler.triggerElementInViewportAnimation();
},
// Trigger scroll on debounce
triggerDebounce: function triggerDebounce() {// console.log('Debounce scroll');
},
// Trigger scroll on the flight
triggerSmooth: function triggerSmooth() {
// console.log('Smooth scroll');
ScrollHandler.detectScrollDirection();
ScrollHandler.toggleStickyNavigation();
},
// Detect if part of a given element is visible in the viewport
// El must be a node element
detectIfElementIsPartlyInViewport: function detectIfElementIsPartlyInViewport(el) {
if (isset(el)) {
var rect = el.getBoundingClientRect(); // DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 }
var windowHeight = window.innerHeight || document.documentElement.clientHeight;
var windowWidth = window.innerWidth || document.documentElement.clientWidth;
var vertInView = rect.top <= windowHeight && rect.top + rect.height >= 0;
var horInView = rect.left <= windowWidth && rect.left + rect.width >= 0;
return vertInView && horInView;
}
},
// Detect if a given element is fully visible in the viewport
// El must be a node element
detectIfElementIsFullyInViewport: function detectIfElementIsFullyInViewport(el) {
if (isset(el)) {
var rect = el.getBoundingClientRect();
return rect.top >= 0 && rect.bottom <= window.innerHeight;
}
},
detectScrollDirection: function detectScrollDirection() {
var scrollTopPosition = window.pageYOffset || document.documentElement.scrollTop; // Credits: "https://github.com/qeremy/so/blob/master/so.dom.js#L426"
if (scrollTopPosition >= ScrollHandler.lastScrollTopPosition) {
ScrollHandler.scrollDirectionDown = true;
ScrollHandler.scrollDirectionUp = false;
} else {
ScrollHandler.scrollDirectionDown = false;
ScrollHandler.scrollDirectionUp = true;
}
ScrollHandler.lastScrollTopPosition = scrollTopPosition;
},
// Trigger animation on elements that have 'element-in-viewport' and that are in the viewport
// These animation can only be triggered once, if you want more then that you should write an specific function for this
triggerElementInViewportAnimation: function triggerElementInViewportAnimation() {
var elements = document.querySelectorAll('.element-in-viewport');
var elementsLength = elements.length;
for (var e = 0; e < elementsLength; e++) {
var element = elements[e];
if (ScrollHandler.detectIfElementIsPartlyInViewport(element)) {
element.classList.remove('element-in-viewport');
}
}
},
// ------------------------------ CUSTOM SCROLL HANDLERS ------------------------------------
// Hide or show sticky navigation when header isn't visible
toggleStickyNavigation: function toggleStickyNavigation() {
var mainNavigation = document.querySelector('body >header');
if (isset(mainNavigation)) {
var triggerNavOn = 150;
if (window.innerWidth <= 1225) triggerNavOn = 40; // Show sticky navigation
if (ScrollHandler.lastScrollTopPosition > triggerNavOn) {
mainNavigation.classList.add('sticky');
} // Hide sticky navigation
if (ScrollHandler.lastScrollTopPosition <= triggerNavOn) {
mainNavigation.classList.remove('sticky');
}
}
}
};
ScrollHandler.init();
/* ==========================================================================
Scroll To Click handler
========================================================================== */
var ScrollToHandler = {
init: function init() {
$('.scroll-to-target').bind('click', function () {
ScrollToHandler.scrollToTarget($(this));
return false;
});
},
/**
* Handles click on the mouse with the arrow
*
* @param el
*/
scrollToTarget: function scrollToTarget(el, offset, time) {
offset = isset(offset) ? offset : 50;
time = isset(time) ? time : 800;
var scrollTo = el.prop('href');
scrollTo = scrollTo.substr(scrollTo.indexOf('#') + 1);
var body = $('html,body');
body.animate({
scrollTop: $('#' + scrollTo).offset().top - offset
}, time);
body.on("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove", function () {
body.stop();
});
}
};
ScrollToHandler.init();
/**
* Created by Pascal on 06/12/17.
*/
$(function () {
var headerImageSliderSetting = new SliderSetting({
sliderId: 'header-image-slider',
slideQuery: '#header-image-slider .placeholder figure',
dots: '#header-image-slider .slider-navigation-labels .navigation span',
captions: '#header-image-slider .slider-navigation-labels .caption p',
autoSlider: true,
sliderInterval: 4000
});
headerImageSliderSetting = headerImageSliderSetting.prepareParameters();
var headerImageSlider = new Slider(headerImageSliderSetting).init();
});
function SliderSetting(settingsObject) {
var self = this;
this.sliderId = '';
this.definedPreviousNext = true;
this.autoSlider = false;
this.sliderInterval = 4000;
this.navigationButtons = '';
this.dots = '';
this.captions = '';
this.slideQuery = '';
this.setSliderId = function ($string) {
this.sliderId = $string;
return this;
};
this.setDefinedPreviousNext = function ($boolean) {
this.definedPreviousNext = $boolean;
return this;
};
this.setAutoSlider = function ($boolean) {
this.autoSlider = $boolean;
return this;
};
this.setSliderInterval = function ($integer) {
this.sliderInterval = $integer;
return this;
};
this.setSlideQuery = function ($string) {
this.slideQuery = $string;
return this;
};
this.setNavigationButtons = function ($string) {
this.navigationButtons = $string;
return this;
};
this.setDots = function ($string) {
this.dots = $string;
return this;
};
this.setCaptions = function ($string) {
this.captions = $string;
return this;
};
this.getSliderId = function () {
return this.sliderId;
};
this.getDefinedPreviousNext = function () {
return this.definedPreviousNext;
};
this.getAutoSlider = function () {
return this.autoSlider;
};
this.getSliderInterval = function () {
return this.sliderInterval;
};
this.getSlideQuery = function () {
return this.slideQuery;
};
this.getNavigationButtons = function () {
return this.navigationButtons;
};
this.getDots = function () {
return this.dots;
};
this.getCaptions = function () {
return this.captions;
}; // Invert setters to getters
this.prepareParameters = function () {
return {
sliderId: self.getSliderId(),
definedPreviousNext: self.getDefinedPreviousNext(),
autoSlider: self.getAutoSlider(),
sliderInterval: self.getSliderInterval(),
navigationButtons: self.getNavigationButtons(),
dots: self.getDots(),
captions: self.getCaptions(),
slideQuery: self.getSlideQuery()
};
}; // Mass assign settings
this.fill = function () {
// Object.keys(settingsObject).forEach(function (key) {
// self[key] = settingsObject[key];
// });
var settingsObjectKeys = Object.keys(settingsObject);
var settingsObjectLength = settingsObjectKeys.length;
for (var i = 0; i < settingsObjectLength; i++) {
var key = settingsObjectKeys[i];
self[key] = settingsObject[key];
}
};
this.fill();
return {
sliderId: self.setSliderId,
definedPreviousNext: self.setDefinedPreviousNext,
autoSlider: self.setAutoSlider,
sliderInterval: self.setSliderInterval,
navigationButtons: self.setNavigationButtons,
dots: self.setDots,
captions: self.setCaptions,
slideQuery: self.setSlideQuery,
prepareParameters: self.prepareParameters
};
}
function Slider(settings) {
//Define Slider object
var self = this;
this.sliderObject = ''; //SlideParameters
this.activeSlideId = 0;
this.previousSlideId = 0;
this.nextSlideId = 0;
this.availableSlides = 1;
this.slides = [];
this.autoSliderInterval = null;
this.settings = {};
this.init = function () {
//Append settings to self
this.settings = settings; //Assign needed elements and calculations
this.sliderObject = document.getElementById(this.settings.sliderId);
this.slides = document.querySelectorAll(this.settings.slideQuery);
this.availableSlides = this.slides.length;
this.activeSlideId = 0; //Define previous and next if we want to use those
if (self.settings.definedPreviousNext) this.setPreviousAndNextSlide(); // Set active slide (and possible previous and next classes)
this.setSlide(); // Swipe interaction
$(this.sliderObject).swipe({
swipeLeft: function swipeLeft() {
self.resetAutoSlider();
self.nextSlide();
self.setSlide();
},
swipeRight: function swipeRight() {
self.resetAutoSlider();
self.previousSlide();
self.setSlide();
}
});
if (this.settings.navigationButtons != '') {
// Click interaction
var navigationButtons = document.querySelectorAll(this.settings.navigationButtons);
var navigationButtonsLength = navigationButtons.length;
for (var i = 0; i < navigationButtonsLength; i++) {
var navigationButton = navigationButtons[i];
navigationButton.addEventListener('click', function () {
self.clickNavigationButton(this);
});
}
}
if (this.settings.dots != '') {
// Click interaction
var dots = document.querySelectorAll(this.settings.dots);
var dotsLength = dots.length;
for (var i = 0; i < dotsLength; i++) {
var dot = dots[i];
dot.addEventListener('click', function () {
self.clickDot(this);
});
}
}
self.autoSlider();
};
this.autoSlider = function () {
if (this.autoSliderInterval !== null) clearInterval(this.autoSliderInterval);
if (this.settings.autoSlider && Number.isInteger(this.settings.sliderInterval)) {
this.autoSliderInterval = setInterval(function () {
self.nextSlide();
self.setSlide();
}, this.settings.sliderInterval);
}
};
this.resetAutoSlider = self.autoSlider;
this.nextSlide = function () {
this.activeSlideId++;
if (this.activeSlideId >= this.availableSlides) this.activeSlideId = 0;
if (self.settings.definedPreviousNext) this.setPreviousAndNextSlide();
};
this.previousSlide = function () {
this.activeSlideId--;
if (this.activeSlideId < 0) this.activeSlideId = this.availableSlides - 1;
if (self.settings.definedPreviousNext) this.setPreviousAndNextSlide();
};
this.setPreviousAndNextSlide = function () {
this.nextSlideId = this.activeSlideId + 1;
if (this.nextSlideId >= this.availableSlides) this.nextSlideId = 0;
this.previousSlideId = this.activeSlideId - 1;
if (this.previousSlideId < 0) this.previousSlideId = this.availableSlides - 1;
};
this.setSlide = function () {
// Loop through the form elements
var slidesLength = self.slides.length;
for (var i = 0; i < slidesLength; i++) {
var slide = self.slides[i]; // Convert dataset attribute to desired type
var slideOrder = parseInt(slide.getAttribute('data-order')); // Remove and set active for all slides
if (slideOrder !== self.activeSlideId) slide.classList.remove('active');else slide.classList.add('active'); // If we use the previous and next, also set those classes
if (self.settings.definedPreviousNext) {
if (slideOrder !== self.previousSlideId) slide.classList.remove('previous');else slide.classList.add('previous');
if (slideOrder !== self.nextSlideId) slide.classList.remove('next');else slide.classList.add('next');
}
}
if (self.settings.dots != '') {
self.setActiveDot();
}
if (self.settings.captions != '') {
self.setActiveCaption();
}
};
this.clickNavigationButton = function (navButton) {
self.activeSlideId = parseInt(navButton.getAttribute('data-order'));
if (self.settings.definedPreviousNext) self.setPreviousAndNextSlide();
self.setSlide();
var next = document.querySelector(self.settings.navigationButtons + '.next');
var previous = document.querySelector(self.settings.navigationButtons + '.previous');
next.setAttribute('data-order', self.nextSlideId);
previous.setAttribute('data-order', self.previousSlideId);
self.resetAutoSlider(); // next.querySelector('p').innerHTML = self.slides[self.nextSlideId].dataset.name;
// previous.querySelector('p').innerHTML = self.slides[self.previousSlideId].dataset.name;
};
this.clickDot = function (clickedDot) {
self.activeSlideId = parseInt(clickedDot.getAttribute('data-order'));
self.setSlide();
self.resetAutoSlider();
};
this.setActiveDot = function () {
var dots = document.querySelectorAll(this.settings.dots);
var dotsLength = dots.length;
for (var i = 0; i < dotsLength; i++) {
var dot = dots[i];
dotOrder = parseInt(dot.getAttribute('data-order'));
if (dotOrder !== self.activeSlideId) dot.classList.remove('active');else dot.classList.add('active');
}
};
this.setActiveCaption = function () {
var captions = document.querySelectorAll(this.settings.captions);
var captionsLength = captions.length;
for (var i = 0; i < captionsLength; i++) {
var caption = captions[i];
captionOrder = parseInt(caption.getAttribute('data-order'));
if (captionOrder !== self.activeSlideId) caption.classList.remove('active');else caption.classList.add('active');
}
};
}
/* ==========================================================================
Youtube handler
========================================================================== */
var YoutubeHandler = {
elementId: 'ytplayer',
youtubeId: '',
player: '',
homeVideo: false,
/**
*
*/
init: function init() {
var youtubeElement = document.getElementById(YoutubeHandler.elementId);
if (isset(youtubeElement)) {
YoutubeHandler.youtubeId = youtubeElement.getAttribute('data-ytlink');
YoutubeHandler.initVideo();
document.getElementById('trigger-video-button').addEventListener('click', function () {
YoutubeHandler.homeVideo = true;
YoutubeHandler.enableHomeVideoFormation();
});
}
},
/**
* Check if external script is loaded
*
*/
initVideo: function initVideo() {
// See if YT variable exists
if (typeof YT == 'undefined' || typeof YT.Player == 'undefined') {
// Setup API ready function
window.onYouTubePlayerAPIReady = function () {
YoutubeHandler.loadPlayer();
}; // Load external script
$.getScript('https://www.youtube.com/iframe_api'); // If YT already exists load player
} else {
YoutubeHandler.loadPlayer();
}
},
/**
* Load Youtube player with parameters
*
*/
loadPlayer: function loadPlayer() {
// Load player
YoutubeHandler.player = new YT.Player(YoutubeHandler.elementId, {
height: 200,
width: 200,
videoId: YoutubeHandler.youtubeId,
host: 'https://www.youtube-nocookie.com',
playerVars: {
modestbranding: 0,
showinfo: 0,
rel: 0,
disablekb: 1
},
events: {
// 'onReady': YoutubeHandler.onReady,
'onStateChange': YoutubeHandler.onStateChange
}
});
},
/**
* Listener for Youtube state change
*
* @param state
*/
onStateChange: function onStateChange(state) {
// Loop video
if (state.data === YT.PlayerState.ENDED && YoutubeHandler.homeVideo) {
// Do stuff
YoutubeHandler.disableHomeVideoFormation();
}
if (state.data === YT.PlayerState.PAUSED && YoutubeHandler.homeVideo) {
YoutubeHandler.preventPausedBufferBlink();
}
},
preventPausedBufferBlink: function preventPausedBufferBlink() {
setTimeout(function () {
if (YoutubeHandler.player.getPlayerState() === YT.PlayerState.PAUSED) {
YoutubeHandler.disableHomeVideoFormation();
}
}, 300);
},
/*
* Slide block for video formation on the home page
*/
enableHomeVideoFormation: function enableHomeVideoFormation() {
var homeIntroSection = document.querySelector('#home .home-intro');
var homeIntroVideoSection = document.querySelector('#home .home-intro .video-block');
var homeIntroVideoHolder = document.querySelector('#home .home-intro .video-block .video-overlay');
if (window.innerWidth >= 1200) {
homeIntroSection.classList.add('video-formation');
setTimeout(function () {
homeIntroVideoSection.classList.add('video-formation-size');
}, 600);
setTimeout(function () {
homeIntroSection.classList.add('video-formation-max-height-size');
}, 1200);
setTimeout(function () {
YoutubeHandler.player.playVideo();
}, 1500);
setTimeout(function () {
homeIntroVideoHolder.classList.add('show-video');
}, 1800);
} else {
homeIntroSection.classList.add('video-formation');
YoutubeHandler.player.playVideo();
}
},
disableHomeVideoFormation: function disableHomeVideoFormation() {
var homeIntroSection = document.querySelector('#home .home-intro');
var homeIntroVideoSection = document.querySelector('#home .home-intro .video-block');
var homeIntroVideoHolder = document.querySelector('#home .home-intro .video-block .video-overlay');
if (window.innerWidth >= 1200) {
homeIntroVideoHolder.classList.remove('show-video');
setTimeout(function () {
homeIntroSection.classList.add('keep-display-settings');
homeIntroSection.classList.remove('video-formation-max-height-size');
}, 600);
setTimeout(function () {
homeIntroSection.classList.remove('keep-display-settings');
homeIntroVideoSection.classList.remove('video-formation-size');
}, 1200);
setTimeout(function () {
homeIntroSection.classList.remove('video-formation');
}, 1800);
} else {
homeIntroSection.classList.remove('video-formation');
}
}
/**
* When player is ready to play
*/
// onReady : function() {
//
// // Show video
// setTimeout(function(){ $('#' + YoutubeHandler.elementId).stop().animate({ opacity: 1 },1000) },800);
//
// // If not on tablet or mobile, play on high quality
// window.player.mute();
// window.player.playVideo();
// window.player.setPlaybackQuality('hd1080');
// },
};
YoutubeHandler.init();