1 /* global twentyseventeenScreenReaderText */
4 // Variables and DOM Caching.
5 var $body = $( 'body' ),
6 $customHeader = $body.find( '.custom-header' ),
7 $branding = $customHeader.find( '.site-branding' ),
8 $navigation = $body.find( '.navigation-top' ),
9 $navWrap = $navigation.find( '.wrap' ),
10 $navMenuItem = $navigation.find( '.menu-item' ),
11 $menuToggle = $navigation.find( '.menu-toggle' ),
12 $menuScrollDown = $body.find( '.menu-scroll-down' ),
13 $sidebar = $body.find( '#secondary' ),
14 $entryContent = $body.find( '.entry-content' ),
15 $formatQuote = $body.find( '.format-quote blockquote' ),
16 isFrontPage = $body.hasClass( 'twentyseventeen-front-page' ) || $body.hasClass( 'home blog' ),
17 navigationFixedClass = 'site-navigation-fixed',
19 navigationOuterHeight,
28 // Ensure the sticky navigation doesn't cover current focused links.
29 $( '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' ).focus( function() {
30 if ( $navigation.hasClass( 'site-navigation-fixed' ) ) {
31 var windowScrollTop = $( window ).scrollTop(),
32 fixedNavHeight = $navigation.height(),
33 itemScrollTop = $( this ).offset().top,
34 offsetDiff = itemScrollTop - windowScrollTop;
36 // Account for Admin bar.
37 if ( $( '#wpadminbar' ).length ) {
38 offsetDiff -= $( '#wpadminbar' ).height();
41 if ( offsetDiff < fixedNavHeight ) {
42 $( window ).scrollTo( itemScrollTop - ( fixedNavHeight + 50 ), 0 );
47 // Set properties of navigation.
48 function setNavProps() {
49 navigationHeight = $navigation.height();
50 navigationOuterHeight = $navigation.outerHeight();
51 navPadding = parseFloat( $navWrap.css( 'padding-top' ) ) * 2;
52 navMenuItemHeight = $navMenuItem.outerHeight() * 2;
53 idealNavHeight = navPadding + navMenuItemHeight;
54 navIsNotTooTall = navigationHeight <= idealNavHeight;
57 // Make navigation 'stick'.
58 function adjustScrollClass() {
60 // Make sure we're not on a mobile screen.
61 if ( 'none' === $menuToggle.css( 'display' ) ) {
63 // Make sure the nav isn't taller than two rows.
64 if ( navIsNotTooTall ) {
66 // When there's a custom header image or video, the header offset includes the height of the navigation.
67 if ( isFrontPage && ( $body.hasClass( 'has-header-image' ) || $body.hasClass( 'has-header-video' ) ) ) {
68 headerOffset = $customHeader.innerHeight() - navigationOuterHeight;
70 headerOffset = $customHeader.innerHeight();
73 // If the scroll is more than the custom header, set the fixed class.
74 if ( $( window ).scrollTop() >= headerOffset ) {
75 $navigation.addClass( navigationFixedClass );
77 $navigation.removeClass( navigationFixedClass );
82 // Remove 'fixed' class if nav is taller than two rows.
83 $navigation.removeClass( navigationFixedClass );
88 // Set margins of branding in header.
89 function adjustHeaderHeight() {
90 if ( 'none' === $menuToggle.css( 'display' ) ) {
92 // The margin should be applied to different elements on front-page or home vs interior pages.
94 $branding.css( 'margin-bottom', navigationOuterHeight );
96 $customHeader.css( 'margin-bottom', navigationOuterHeight );
100 $customHeader.css( 'margin-bottom', '0' );
101 $branding.css( 'margin-bottom', '0' );
105 // Set icon for quotes.
106 function setQuotesIcon() {
107 $( twentyseventeenScreenReaderText.quote ).prependTo( $formatQuote );
110 // Add 'below-entry-meta' class to elements.
111 function belowEntryMetaClass( param ) {
112 var sidebarPos, sidebarPosBottom;
114 if ( ! $body.hasClass( 'has-sidebar' ) || (
115 $body.hasClass( 'search' ) ||
116 $body.hasClass( 'single-attachment' ) ||
117 $body.hasClass( 'error404' ) ||
118 $body.hasClass( 'twentyseventeen-front-page' )
123 sidebarPos = $sidebar.offset();
124 sidebarPosBottom = sidebarPos.top + ( $sidebar.height() + 28 );
126 $entryContent.find( param ).each( function() {
127 var $element = $( this ),
128 elementPos = $element.offset(),
129 elementPosTop = elementPos.top;
131 // Add 'below-entry-meta' to elements below the entry meta.
132 if ( elementPosTop > sidebarPosBottom ) {
133 $element.addClass( 'below-entry-meta' );
135 $element.removeClass( 'below-entry-meta' );
141 * Test if inline SVGs are supported.
142 * @link https://github.com/Modernizr/Modernizr/
144 function supportsInlineSVG() {
145 var div = document.createElement( 'div' );
146 div.innerHTML = '<svg/>';
147 return 'http://www.w3.org/2000/svg' === ( 'undefined' !== typeof SVGRect && div.firstChild && div.firstChild.namespaceURI );
151 * Test if an iOS device.
153 function checkiOS() {
154 return /iPad|iPhone|iPod/.test(navigator.userAgent) && ! window.MSStream;
158 * Test if background-attachment: fixed is supported.
159 * @link http://stackoverflow.com/questions/14115080/detect-support-for-background-attachment-fixed
161 function supportsFixedBackground() {
162 var el = document.createElement('div'),
166 if ( ! ( 'backgroundAttachment' in el.style ) || checkiOS() ) {
169 el.style.backgroundAttachment = 'fixed';
170 isSupported = ( 'fixed' === el.style.backgroundAttachment );
178 // Fire on document ready.
179 $( document ).ready( function() {
181 // If navigation menu is present on page, setNavProps and adjustScrollClass.
182 if ( $navigation.length ) {
187 // If 'Scroll Down' arrow in present on page, calculate scroll offset and bind an event handler to the click event.
188 if ( $menuScrollDown.length ) {
190 if ( $( 'body' ).hasClass( 'admin-bar' ) ) {
193 if ( $( 'body' ).hasClass( 'blog' ) ) {
194 menuTop -= 30; // The div for latest posts has no space above content, add some to account for this.
196 if ( ! $navigation.length ) {
197 navigationOuterHeight = 0;
200 $menuScrollDown.click( function( e ) {
202 $( window ).scrollTo( '#primary', {
204 offset: { top: menuTop - navigationOuterHeight }
209 adjustHeaderHeight();
211 if ( true === supportsInlineSVG() ) {
212 document.documentElement.className = document.documentElement.className.replace( /(\s*)no-svg(\s*)/, '$1svg$2' );
215 if ( true === supportsFixedBackground() ) {
216 document.documentElement.className += ' background-fixed';
220 // If navigation menu is present on page, adjust it on scroll and screen resize.
221 if ( $navigation.length ) {
223 // On scroll, we want to stick/unstick the navigation.
224 $( window ).on( 'scroll', function() {
226 adjustHeaderHeight();
229 // Also want to make sure the navigation is where it should be on resize.
230 $( window ).resize( function() {
232 setTimeout( adjustScrollClass, 500 );
236 $( window ).resize( function() {
237 clearTimeout( resizeTimer );
238 resizeTimer = setTimeout( function() {
239 belowEntryMetaClass( 'blockquote.alignleft, blockquote.alignright' );
241 setTimeout( adjustHeaderHeight, 1000 );
244 // Add header video class after the video is loaded.
245 $( document ).on( 'wp-custom-header-video-loaded', function() {
246 $body.addClass( 'has-header-video' );