/* global.js ========= https://docs.google.com/document/d/19OR8ot3V48Xxy0T7NKPwuxVHY60Q5cejE3cCetNzZxQ/edit */ /* FUNCTIONS ========= */ // fOnDropdownHover() - When the dropdown is being hovered open it // fOnDropdownNoLongerHover() - When the dropdown is no longer being hovered close it // fOnBodyClickWhilstMobileMenuOpen() - Functional event that is registered onto body.click when the mobile menu is opened, and removed when closed // fOpenMobileMenu() - Simply opens the mobile menu // fCloseMobileMenu() - You guessed it, closes the mobile menu /* GLOBAL VARIABLES ================ */ // Store if we have switched the footer to be absolute or not var bIsFooterPositionedAbsolute = false; // Store if the mobile menu it open or not var bIsMobileMenuOpen = false; /* On Document Loaded ================== Called by Jquery event handler when the document is ready (When content has been loaded) */ $( document ).ready( function() { /* INITATE NAVIGATION DROPDOWNS ============================ Make it so when we hover the navigation elements / click them the navigation menu displays */ // On mouse over dropdown container $(".dropdown-root-container").mouseover( function() { // If we are on desktop if( $(window).width() >= 992 ) { // Open the menu fOnDropdownHover( $(this) ); } }); // On mouse leave dropdown container $(".dropdown-root-container").mouseleave( function() { // If we are on desktop if( $(window).width() >= 992 ) { // Close the menu fOnDropdownNoLongerHover( $(this) ); } }); // On mouse click $(".dropdown-root-container").click( function() { // If the menu is open if( $(this).children().last().is(":visible") ) { // Then close the menu fOnDropdownNoLongerHover( $(this) ); } // If the menu is closed else { // Then open the menu fOnDropdownHover( $(this) ); } }); // On window resize, call the callback $(window).on( "resize", fOnWindowResize ); // Manuall invoke the window resize fOnWindowResize(); // Each time an image loads, we want to call the resize function to ensure everything is correctly sized / positioned $("img").on('load', function() { // Manuall invoke the window resize fOnWindowResize(); }); }); /* fOnWindowResize() ================= */ function fOnWindowResize() { // If we have the newsletter input box if( $(".newsletter-input-boxes").length ) { // Store the target height of the sign up button var nTargetHeight = $(".sign-up-button").outerHeight(true); // Set the height of the newsletter input box $(".newsletter-input-boxes").css( { height : nTargetHeight + "px" } ); } // If we are not on the homepage if( !$("#homepage-div").length ) { // Store the footer height var nFooterHeight = $(".footer").outerHeight(true); } // if we are on the homepage else { // Update the footer relative element $(".footer-relative-container").css( {height : nFooterHeight + "px"} ); } // If we are on desktop if( $(window).width() >= 992 ) { // If the header icons are attatched to the navbar (When they now need to be in the header) if( $(".header-icons-mobile-container").children().length != 0 ) { // Insert the header icons in the correct position $(".menu-items").insertBefore( $(".header-icons-location") ); } // If the social icons are attatched to the header (When they now need to be in the footer) if( $(".social-icons-mobile-container").children().length != 0 ) { // Insert the social icons in the correct position (footer) $(".social-icons").insertBefore( $(".social-icons-location") ); } } // If we are on mobile else { // If we haven't moved the header icons yet if( $(".header-icons-mobile-container").children().length == 0 ) { // Insert the header icons in the correct position $(".header-icons-mobile-container").append( $(".menu-items") ); } // If we haven't moved the social icons yet if( $(".social-icons-mobile-container").children().length == 0 ) { // Insert the social icons in the correct position (header) $(".social-icons-mobile-container").append( $(".social-icons") ); } } // If we are on mobile if( $(window).width() <= 500 ) { // If we have dropdown elements that are facing the right, make them go left on mobile if( $(".dropdown-menu-right").length ) { // Add the class to store that this element had the right dropdown on tablet/desktop $(".dropdown-menu-right").addClass("dropdown-menu-right-desktop"); // Remove the dropdown class $(".dropdown-menu-right").removeClass("dropdown-menu-right"); } } // If we are not on mobile (On desktop/tablet) else { // If we have dropdown elements that should be facing the right if( $(".dropdown-menu-right-desktop").length ) { // Add the dropdown class $(".dropdown-menu-right-desktop").addClass("dropdown-menu-right"); // Remove the class to store that this element had the right dropdown on tablet/desktop $(".dropdown-menu-right-desktop").removeClass("dropdown-menu-right-desktop"); } } /* ENSURE FOOTER IS AT BOTTOM ========================== If we are on a page where there is hardly any content within the site, we make the footer positioned absolute and move it to the bottom of the screen. */ // If we are not on the homepage if( !$("#homepage-div").length ) { // Store the docunment height var nBodyHeight = $(document.body).height(); // If the footer is positioned absolute, then the footer wont be taken acount into the body size if( bIsFooterPositionedAbsolute ) { // Add the footer size to the body height (we minus the 4 pixels as a offset from the delay of this being called after browser has done rendering) nBodyHeight += $(".footer").outerHeight(true) - 4; } // If the body height is smaller than the browser size if( nBodyHeight <= $(window).height() ) { // If we haven't already changed the state of the footer if( !bIsFooterPositionedAbsolute ) { // Set the footer state of being position absolute to true bIsFooterPositionedAbsolute = true; // Make the footer absolute, this makes the white appear above the footer instead of below it $(".footer").css( { position : "absolute", bottom : "0px" } ); } } // If the body height is bigger than the window height, then there's nothing to hide, so we can go on as nomral else { // If we havne't already changed the state of the footer if( bIsFooterPositionedAbsolute ) { // Set the footer state of being position absolute to false bIsFooterPositionedAbsolute = false; // Make the footer continue normal document flow $(".footer").css( { position : "relative", bottom : "" } ); } } } } /* fOnDropdownHover() ================== Opens the releavnt dropdown menu for the navigation */ function fOnDropdownHover( oElement) { // Store the dropdown menu var oDropdownMenu = oElement.children().last(); // If the dropdown menu isn't active if( !oDropdownMenu.hasClass("menu-is-active") ) { // Add the menu is active class oDropdownMenu.addClass("menu-is-active"); // Store the first child (first col-) var oMenuFirstChild = oDropdownMenu.children().first().children().first(); // Stop any animations playing (cancels close animation if required) oDropdownMenu.stop(); // Remove the menu is active closing class incase we have canceld the closing oDropdownMenu.removeClass("menu-is-closing"); // Set the opaciy to 0 oDropdownMenu.css( { opacity : 0 } ); // Show the dropdown menu oDropdownMenu.show(); // If the dropdown menu's outer width is too small (The navigation looks squished) and its positined to the right of the screen if( oDropdownMenu.outerWidth() <= 400 && oDropdownMenu.offset().left >= ($(window).width() / 2) ) { // If the first child has the class of col-md-6, then it's a half menu if( oMenuFirstChild.hasClass("col-md-6") ) { // Store the last child (Second col-6) var oMenuLastChild = oDropdownMenu.children().first().children().last(); // Remove the col-md-6 class oMenuFirstChild.removeClass("col-md-6"); // Add the col-md-12 class oMenuFirstChild.addClass("col-md-12"); // Add a class to track if the menu used to have col-md-6 oMenuFirstChild.addClass("had-col-md-6"); // Remove the col-md-6 class oMenuLastChild.removeClass("col-md-6"); // Add the col-md-12 class oMenuLastChild.addClass("col-md-12"); // Add a class to track if the menu used to have col-md-6 oMenuLastChild.addClass("had-col-md-6"); } } // Set the opaciy to 1 oDropdownMenu.animate( { opacity : 1 } , 500 ); } } /* fOnDropdownNoLongerHover() ========================== closes the releavnt dropdown menu for the navigation */ function fOnDropdownNoLongerHover( oElement ) { // Store the dropdown menu var oDropdownMenu = oElement.children().last(); // If the dropdown menu is active if( oDropdownMenu.hasClass("menu-is-active") ) { // Remove the dropdown menu class oDropdownMenu.removeClass("menu-is-active"); // Add the removing class oDropdownMenu.addClass("menu-is-closing"); // Set the opaciy to 0 oDropdownMenu.stop().animate( { opacity : 0 } , 300, function() { // If we are still wanting to close the menu if( oDropdownMenu.hasClass("menu-is-closing") ) { // Hide the dropdown menu oDropdownMenu.hide(); // Remove the dropdown closing class oDropdownMenu.removeClass("menu-is-closing"); } }); } } /* fOnBodyClickWhilstMobileMenuOpen( oEvent ) ========================================== To make the user interface more friendly, we can detect when the user has tapped to exit the mobile menu, this function is added as an event when the menu opens, and removed when the menu closes */ function fOnBodyClickWhilstMobileMenuOpen( oEvent ) { // First detect if the mobile menu is open or not, if it is then carry on if( bIsMobileMenuOpen ) { // Store the parent navigational element var oNavigationWrapper = $("#header-navigation"); // Store the clicked element var oClickedElement = $(oEvent.target); // If the element clicked isn't part of the navigational structure (if the user has clicked an element outside of the menu) if( oClickedElement !== oNavigationWrapper && !oNavigationWrapper[0].contains( oClickedElement[0] ) && !oClickedElement.hasClass("hamburger-menu") ) { // Close the navigation menu, as the user has clicked outside of the navigation wrapper fCloseMobileMenu(); } } } /* fOpenMobileMenu() ================= Open the mobile menu */ function fOpenMobileMenu() { // Add the css class to activate the side menu $("#header-navigation").addClass("active-mobile-menu"); // Set the varaible that stores the state of the menu bIsMobileMenuOpen = true; // Set timeout for 300ms setTimeout(function () { // Add the on click event for the body $('body').click( fOnBodyClickWhilstMobileMenuOpen ); }, 300); } /* fCloseMobileMenu() ================= Close the mobile menu */ function fCloseMobileMenu() { // Add the css class to activate the side menu $("#header-navigation").removeClass("active-mobile-menu"); // Set the varaible that stores the state of the menu bIsMobileMenuOpen = false; // Remove the on click event for the body $('body').unbind("click", fOnBodyClickWhilstMobileMenuOpen); }