import './blocks/cb.js'; import './blocks/accordion.js'; import './blocks/carousel.js'; import './blocks/cards-grid.js'; import './blocks/featured-tabs.js'; import './blocks/inputs.js'; import './blocks/marquee.js'; import './blocks/home-scroll-banner.js'; import './blocks/page-title-banner.js'; import './blocks/paragraph.js'; import './blocks/secondary-nav.js'; import './blocks/tabs.js'; import './blocks/tease.js'; /** * Global scripts */ window.addEventListener('load', (event) => { /** * Vars */ //functional let vh = '100vh' let currentScrollPos = 0 let prevScrollPos = 0 let menuToggledScrollPos let menuIsOpen = false let desktopMenuIsOpen = false let mobileMenuIsOpen = false //media query const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream const isDesktop = window.matchMedia('(min-width: 80rem)') // DOM elements const body = document.body const header = document.querySelector('.site-header') const logo = document.querySelector('.site-logo') const a11y_ariaexpanded = document.querySelectorAll('[aria-expanded="false"]') const mainNav = document.getElementById('site-header-main-nav') const menuItems = document.querySelectorAll('#site-header-main-nav > ul > .menu-item-has-children > a') const menuBtn = document.getElementById('menu-btn') const overlay = document.getElementById('overlay') const menuMobile = document.getElementById('menu-mobile') const pageWrapper = document.getElementById('site-content-wrapper') const accordionMenuItems = document.querySelectorAll('[data-toggle-menu-items]') const footer = document.getElementById('site-footer') /** * Throttle */ function throttle(mainFunction, delay) { let timerFlag = null return (...args) => { if (timerFlag === null) { mainFunction(...args) timerFlag = setTimeout(() => { timerFlag = null }, delay) } } } /** * Check if iOS, then set --vh */ if (isIOS && window.matchMedia("(max-width: 1024px)").matches) { document.documentElement.classList.add('is-ios') } function set100vh() { // If window size is iPad or smaller, then use JS to set screen height. if (isIOS && window.matchMedia("(max-width: 1024px)").matches) { vh = `${window.innerHeight}px` document.documentElement.style.setProperty("--vh", vh) } } set100vh() /** * WAI-ARIA toggle aria-expanded */ function updateAriaExpanded(item){ const ariaexpanded = item.getAttribute('aria-expanded') if (ariaexpanded == 'true') { item.setAttribute('aria-expanded', 'false') } else { item.setAttribute('aria-expanded', 'true') } } a11y_ariaexpanded.forEach((item) => { item.addEventListener('click', function () { updateAriaExpanded(this) }) }) /** * Get header height */ let headerHeight function getHeaderHeight(){ headerHeight = header.clientHeight return `${headerHeight}px` } function setHeaderHeightVar(){ document.documentElement.style.setProperty("--header-height", getHeaderHeight()) } setHeaderHeightVar() /** * Hide header if scrolling down, show if scrolling up */ window.addEventListener('scroll', () => { currentScrollPos = window.scrollY // const currentScrollPos = window.scrollY //if you start scrolling add class if (currentScrollPos > headerHeight && !menuIsOpen) { body.classList.add('is-scrolled') } else{ body.classList.remove('is-scrolled') } // if scrolling down, hide header and position logo to the left // if scrolling up, show header and logo in initial position if (prevScrollPos > headerHeight && prevScrollPos < currentScrollPos && !menuIsOpen) { header.classList.add('is-hidden') logo.classList.add('is-visible') overlay.classList.remove('is-active') } else if (prevScrollPos >= currentScrollPos && !menuIsOpen) { header.classList.remove('is-hidden') logo.classList.remove('is-visible') } prevScrollPos = currentScrollPos }) /** * Menu */ function toggleMenuSharedElements(toggle = true){ if (!menuIsOpen) { body.classList.add('has-menu-toggled') menuBtn.classList.add('is-active') menuBtn.classList.add('is-toggled') overlay.classList.add('is-active') menuIsOpen = true } else if (toggle) { body.classList.remove('has-menu-toggled') menuBtn.classList.remove('is-active') menuBtn.classList.remove('is-toggled') overlay.classList.remove('is-active') menuIsOpen = false } } // when menu is toggled, set margin top based // on scrolled px and restore scroll after menu is closed function setScrolledMarginContent(scrolled){ if (mobileMenuIsOpen || desktopMenuIsOpen) { pageWrapper.style.marginTop = 0 document.body.scrollTop = menuToggledScrollPos document.body.scrollTop = menuToggledScrollPos document.documentElement.scrollTop = menuToggledScrollPos } else { pageWrapper.style.marginTop = `-${scrolled}px` } menuToggledScrollPos = scrolled } function toggleMobileMenu(forceClosing = null){ toggleMenuSharedElements() if (forceClosing) { menuMobile.classList.remove('is-toggled') } else { menuMobile.classList.toggle('is-toggled') // if (menuIsOpen) { // menuMobile.animate( // [ // { height: '0px' }, // { height: `${menuMobile.clientHeight}px` } // ], // { // duration: 500, // easing: 'ease-out' // } // ) // } else { // menuMobile.animate( // [ // { height: '0px' }, // { height: `${menuMobile.clientHeight}px` } // ], // { // duration: 500, // easing: 'ease-out' // } // ) // } } closeAllAccordionMenuItems() // set margin on page wapper // and restore scrolled position when you close menu setScrolledMarginContent(currentScrollPos) menuIsOpen ? mobileMenuIsOpen = true : mobileMenuIsOpen = false } let previousClickedItem function toggleDesktopMenu(clickedItem = null){ if (clickedItem == null) { toggleMenuSharedElements() openSubMenu() } else if (clickedItem == previousClickedItem || previousClickedItem == null || !desktopMenuIsOpen) { // if desktop menu is not toggled or you are toggling menu item toggleMenuSharedElements() openSubMenu(clickedItem) } else if (clickedItem != previousClickedItem && clickedItem != null){ // if you are swapping submenu openSubMenu(clickedItem, false) } // assign previous clicked item to currently clicked item previousClickedItem = clickedItem // toggle/remove class on all menu items menuItems.forEach((item) => { const itemListItem = item.parentElement if (itemListItem != clickedItem) { itemListItem.classList.remove('is-toggled') } else { itemListItem.classList.toggle('is-toggled') } }) // set margin on page wapper // and restore scrolled position when you close menu setScrolledMarginContent(currentScrollPos) menuIsOpen ? desktopMenuIsOpen = true : desktopMenuIsOpen = false } function toggleMenuWhenResized(){ // if mobile menu is open and window resized to desktop if (mobileMenuIsOpen && isDesktop.matches){ toggleMenuSharedElements() toggleMobileMenu(true) menuIsOpen = false } // if desktop menu is open and window resized to mobile if (desktopMenuIsOpen && !isDesktop.matches){ toggleMenuSharedElements() toggleDesktopMenu() menuIsOpen = false } } // animate desktop dropdown and toggle function openSubMenu(clickedItem, animate = true){ let submenu if (clickedItem) { //if there's a clicked item get submenu descendante submenu = clickedItem.querySelector('.site-header-navbar-submenu-0') } else { // if there isn't a clicked item (eg: X button), select visible menus submenu = document.querySelector('.site-header-navbar-submenu-0.is-visible') clickedItem = document.querySelector('#site-header-main-nav .menu-item-has-children.is-toggled') console.log(clickedItem) } if (clickedItem.classList.contains('is-toggled')) { // if desktop menu is already open and click on already toggled item // remove classes and animate submenu to 0px height mainNav.classList.remove('is-toggled') submenu.classList.add('is-closing') submenu.animate( [ { height: `${submenu.clientHeight}px` }, { height: 0 } ], { duration: 250, delay: 250, easing: 'ease-out' } ) // timeout animation setTimeout(() => { submenu.classList.remove('is-visible') submenu.classList.remove('is-closing') }, 500); } else if (!animate){ // if desktop menu is open and click on item not yet toggled // swap submenu container without animations [...document.querySelectorAll('.site-header-navbar-submenu-0')].forEach(s=>{ if(submenu != s){ s.classList.remove('is-visible') } else { submenu.classList.add('is-visible') } }) } else { // if desktop menu is not open and click on item // show and animate submenu submenu.classList.add('is-visible') submenu.animate( [ { height: 0 }, { height: `${submenu.clientHeight}px` } ], { duration: 250, easing: 'ease-out' } ) setTimeout(() => { mainNav.classList.add('is-toggled') }, 500); } } function cbToggleDesktopMenu(event){ const item = event.target.parentElement toggleDesktopMenu(item) } // Throttle the fetchData function with a delay of 5000 ms const throttledtoggleDesktopMenu = throttle(cbToggleDesktopMenu, 500) menuItems.forEach(item => { item.addEventListener('click', throttledtoggleDesktopMenu) }) menuBtn.addEventListener('click', function(){ if (isDesktop.matches) { console.log('test') toggleDesktopMenu() } else { toggleMobileMenu() } }) //close all accordion menu items function closeAllAccordionMenuItems(){ accordionMenuItems.forEach(item => { item.parentElement.parentElement.classList.remove('is-toggled') item.parentElement.parentElement.setAttribute('aria-expanded', 'false') }) } accordionMenuItems.forEach(button => { button.addEventListener('click', function(){ // get <li> const clickedItem = this.parentElement.parentElement // get nesting of clicked item (from button) const nesting = this.getAttribute('data-toggle-menu-items') if (nesting == 0 && clickedItem.classList.contains('is-toggled')) { // if is first level and already opened, // when clicked close all items closeAllAccordionMenuItems() } else { // when you click on item, close other items on same nesting level // [...document.querySelectorAll(`[data-toggle-menu-items="${nesting}"]`)].forEach(i=>{if(this != i){i.parentElement.parentElement.classList.remove('is-toggled')}}) // toggle clicked item clickedItem.classList.toggle('is-toggled') } }) }) // if click on overlay close menu overlay.addEventListener('click', function(){ // toggleMenuSharedElements() if (isDesktop.matches) { toggleDesktopMenu() } else { toggleMobileMenu() } }) /** * Filters */ const filters = document.querySelectorAll('.block-filters') filters.forEach(filter => { const trigger = filter.querySelector('.block-filters__header') const content = filter.querySelector('.block-filters__inner') trigger.addEventListener('click', function(){ trigger.classList.toggle('is-toggled') content.classList.toggle('is-visible') }) }) /** * Back to top */ document.getElementById('backToTop').addEventListener('click', function(){ window.scrollTo({ top: 0, behavior: 'smooth' }) }) /** * Footer observer */ //when footer is in viewport, restore logo position let footerObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if(entry.isIntersecting){ body.classList.add('footer-in-viewport') } else { body.classList.remove('footer-in-viewport') } }) }, { rootMargin: '0px' }) footerObserver.observe(footer) /** * Window resize function callbacks */ const resizeHandler = function(){ // set vh set100vh() // get header height setHeaderHeightVar() // when resizing disable menu if toggled toggleMenuWhenResized() } window.addEventListener('resize', resizeHandler) /** * Keyboard related functions and events */ document.onkeydown = function(evt) { evt = evt || window.event; var isEscape = false; if ('key' in evt) { isEscape = (evt.key === 'Escape' || evt.key === 'Esc'); } else { isEscape = (evt.keyCode === 27); } // if menu is open and press escape, toggle desktop or mobile menu // based on media query if (isEscape && menuIsOpen) { toggleMenuSharedElements(false) if (isDesktop.matches) { toggleDesktopMenu() } else { toggleMobileMenu() } } } })