/* global twentyseventeenScreenReaderText */ (function( $ ) { // Variables and DOM Caching. var $body = $( 'body' ), $customHeader = $body.find( '.custom-header' ), $branding = $customHeader.find( '.site-branding' ), $navigation = $body.find( '.navigation-top' ), $navWrap = $navigation.find( '.wrap' ), $navMenuItem = $navigation.find( '.menu-item' ), $menuToggle = $navigation.find( '.menu-toggle' ), $menuScrollDown = $body.find( '.menu-scroll-down' ), $sidebar = $body.find( '#secondary' ), $entryContent = $body.find( '.entry-content' ), $formatQuote = $body.find( '.format-quote blockquote' ), isFrontPage = $body.hasClass( 'twentyseventeen-front-page' ) || $body.hasClass( 'home blog' ), navigationFixedClass = 'site-navigation-fixed', navigationHeight, navigationOuterHeight, navPadding, navMenuItemHeight, idealNavHeight, navIsNotTooTall, headerOffset, menuTop = 0, resizeTimer; // Ensure the sticky navigation doesn't cover current focused links. $( 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex], [contenteditable]', '.site-content-contain' ).filter( ':visible' ).on( 'focus', function() { if ( $navigation.hasClass( 'site-navigation-fixed' ) ) { var windowScrollTop = $( window ).scrollTop(), fixedNavHeight = $navigation.height(), itemScrollTop = $( this ).offset().top, offsetDiff = itemScrollTop - windowScrollTop; // Account for Admin bar. if ( $( '#wpadminbar' ).length ) { offsetDiff -= $( '#wpadminbar' ).height(); } if ( offsetDiff < fixedNavHeight ) { $( window ).scrollTo( itemScrollTop - ( fixedNavHeight + 50 ), 0 ); } } }); // Set properties of navigation. function setNavProps() { navigationHeight = $navigation.height(); navigationOuterHeight = $navigation.outerHeight(); navPadding = parseFloat( $navWrap.css( 'padding-top' ) ) * 2; navMenuItemHeight = $navMenuItem.outerHeight() * 2; idealNavHeight = navPadding + navMenuItemHeight; navIsNotTooTall = navigationHeight <= idealNavHeight; } // Make navigation 'stick'. function adjustScrollClass() { // Make sure we're not on a mobile screen. if ( 'none' === $menuToggle.css( 'display' ) ) { // Make sure the nav isn't taller than two rows. if ( navIsNotTooTall ) { // When there's a custom header image or video, the header offset includes the height of the navigation. if ( isFrontPage && ( $body.hasClass( 'has-header-image' ) || $body.hasClass( 'has-header-video' ) ) ) { headerOffset = $customHeader.innerHeight() - navigationOuterHeight; } else { headerOffset = $customHeader.innerHeight(); } // If the scroll is more than the custom header, set the fixed class. if ( $( window ).scrollTop() >= headerOffset ) { $navigation.addClass( navigationFixedClass ); } else { $navigation.removeClass( navigationFixedClass ); } } else { // Remove 'fixed' class if nav is taller than two rows. $navigation.removeClass( navigationFixedClass ); } } } // Set margins of branding in header. function adjustHeaderHeight() { if ( 'none' === $menuToggle.css( 'display' ) ) { // The margin should be applied to different elements on front-page or home vs interior pages. if ( isFrontPage ) { $branding.css( 'margin-bottom', navigationOuterHeight ); } else { $customHeader.css( 'margin-bottom', navigationOuterHeight ); } } else { $customHeader.css( 'margin-bottom', '0' ); $branding.css( 'margin-bottom', '0' ); } } // Set icon for quotes. function setQuotesIcon() { $( twentyseventeenScreenReaderText.quote ).prependTo( $formatQuote ); } // Add 'below-entry-meta' class to elements. function belowEntryMetaClass( param ) { var sidebarPos, sidebarPosBottom; if ( ! $body.hasClass( 'has-sidebar' ) || typeof $sidebar === 'undefined' || $sidebar.length < 1 || ( $body.hasClass( 'search' ) || $body.hasClass( 'single-attachment' ) || $body.hasClass( 'error404' ) || $body.hasClass( 'twentyseventeen-front-page' ) ) ) { return; } sidebarPos = $sidebar.offset(); sidebarPosBottom = sidebarPos.top + ( $sidebar.height() + 28 ); $entryContent.find( param ).each( function() { var $element = $( this ), elementPos = $element.offset(), elementPosTop = elementPos.top; // Add 'below-entry-meta' to elements below the entry meta. if ( elementPosTop > sidebarPosBottom ) { $element.addClass( 'below-entry-meta' ); } else { $element.removeClass( 'below-entry-meta' ); } }); } /* * Test if inline SVGs are supported. * @link https://github.com/Modernizr/Modernizr/ */ function supportsInlineSVG() { var div = document.createElement( 'div' ); div.innerHTML = ''; return 'http://www.w3.org/2000/svg' === ( 'undefined' !== typeof SVGRect && div.firstChild && div.firstChild.namespaceURI ); } /** * Test if an iOS device. */ function checkiOS() { return /iPad|iPhone|iPod/.test(navigator.userAgent) && ! window.MSStream; } /* * Test if background-attachment: fixed is supported. * @link http://stackoverflow.com/questions/14115080/detect-support-for-background-attachment-fixed */ function supportsFixedBackground() { var el = document.createElement('div'), isSupported; try { if ( ! ( 'backgroundAttachment' in el.style ) || checkiOS() ) { return false; } el.style.backgroundAttachment = 'fixed'; isSupported = ( 'fixed' === el.style.backgroundAttachment ); return isSupported; } catch (e) { return false; } } // Fire on document ready. $( function() { // If navigation menu is present on page, setNavProps and adjustScrollClass. if ( $navigation.length ) { setNavProps(); adjustScrollClass(); } // If 'Scroll Down' arrow in present on page, calculate scroll offset and bind an event handler to the click event. if ( $menuScrollDown.length ) { if ( $( 'body' ).hasClass( 'admin-bar' ) ) { menuTop -= 32; } if ( $( 'body' ).hasClass( 'blog' ) ) { menuTop -= 30; // The div for latest posts has no space above content, add some to account for this. } if ( ! $navigation.length ) { navigationOuterHeight = 0; } $menuScrollDown.on( 'click', function( e ) { e.preventDefault(); $( window ).scrollTo( '#primary', { duration: 600, offset: { top: menuTop - navigationOuterHeight } }); }); } adjustHeaderHeight(); setQuotesIcon(); belowEntryMetaClass( 'blockquote.alignleft, blockquote.alignright' ); if ( true === supportsInlineSVG() ) { document.documentElement.className = document.documentElement.className.replace( /(\s*)no-svg(\s*)/, '$1svg$2' ); } if ( true === supportsFixedBackground() ) { document.documentElement.className += ' background-fixed'; } } ); // If navigation menu is present on page, adjust it on scroll and screen resize. if ( $navigation.length ) { // On scroll, we want to stick/unstick the navigation. $( window ).on( 'scroll', function() { adjustScrollClass(); adjustHeaderHeight(); }); // Also want to make sure the navigation is where it should be on resize. $( window ).on( 'resize', function() { setNavProps(); setTimeout( adjustScrollClass, 500 ); }); } $( window ).on( 'resize', function() { clearTimeout( resizeTimer ); resizeTimer = setTimeout( function() { belowEntryMetaClass( 'blockquote.alignleft, blockquote.alignright' ); }, 300 ); setTimeout( adjustHeaderHeight, 1000 ); }); // Add header video class after the video is loaded. $( document ).on( 'wp-custom-header-video-loaded', function() { $body.addClass( 'has-header-video' ); }); })( jQuery );