wp/wp-content/themes/twentyfourteen/js/functions.js
changeset 8 c7c34916027a
parent 7 cf61fcea0001
child 9 177826044cd9
equal deleted inserted replaced
7:cf61fcea0001 8:c7c34916027a
     1 /**
       
     2  * Theme functions file
       
     3  *
       
     4  * Contains handlers for navigation, accessibility, header sizing
       
     5  * footer widgets and Featured Content slider
       
     6  *
       
     7  */
       
     8 ( function( $ ) {
       
     9 	var body    = $( 'body' ),
       
    10 		_window = $( window ),
       
    11 		nav, button, menu;
       
    12 
       
    13 	nav = $( '#primary-navigation' );
       
    14 	button = nav.find( '.menu-toggle' );
       
    15 	menu = nav.find( '.nav-menu' );
       
    16 
       
    17 	// Enable menu toggle for small screens.
       
    18 	( function() {
       
    19 		if ( ! nav.length || ! button.length ) {
       
    20 			return;
       
    21 		}
       
    22 
       
    23 		// Hide button if menu is missing or empty.
       
    24 		if ( ! menu.length || ! menu.children().length ) {
       
    25 			button.hide();
       
    26 			return;
       
    27 		}
       
    28 
       
    29 		button.on( 'click.twentyfourteen', function() {
       
    30 			nav.toggleClass( 'toggled-on' );
       
    31 			if ( nav.hasClass( 'toggled-on' ) ) {
       
    32 				$( this ).attr( 'aria-expanded', 'true' );
       
    33 				menu.attr( 'aria-expanded', 'true' );
       
    34 			} else {
       
    35 				$( this ).attr( 'aria-expanded', 'false' );
       
    36 				menu.attr( 'aria-expanded', 'false' );
       
    37 			}
       
    38 		} );
       
    39 	} )();
       
    40 
       
    41 	/*
       
    42 	 * Makes "skip to content" link work correctly in IE9 and Chrome for better
       
    43 	 * accessibility.
       
    44 	 *
       
    45 	 * @link http://www.nczonline.net/blog/2013/01/15/fixing-skip-to-content-links/
       
    46 	 */
       
    47 	_window.on( 'hashchange.twentyfourteen', function() {
       
    48 		var hash = location.hash.substring( 1 ), element;
       
    49 
       
    50 		if ( ! hash ) {
       
    51 			return;
       
    52 		}
       
    53 
       
    54 		element = document.getElementById( hash );
       
    55 
       
    56 		if ( element ) {
       
    57 			if ( ! /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) {
       
    58 				element.tabIndex = -1;
       
    59 			}
       
    60 
       
    61 			element.focus();
       
    62 
       
    63 			// Repositions the window on jump-to-anchor to account for header height.
       
    64 			window.scrollBy( 0, -80 );
       
    65 		}
       
    66 	} );
       
    67 
       
    68 	$( function() {
       
    69 		// Search toggle.
       
    70 		$( '.search-toggle' ).on( 'click.twentyfourteen', function( event ) {
       
    71 			var that    = $( this ),
       
    72 				wrapper = $( '#search-container' ),
       
    73 				container = that.find( 'a' );
       
    74 
       
    75 			that.toggleClass( 'active' );
       
    76 			wrapper.toggleClass( 'hide' );
       
    77 
       
    78 			if ( that.hasClass( 'active' ) ) {
       
    79 				container.attr( 'aria-expanded', 'true' );
       
    80 			} else {
       
    81 				container.attr( 'aria-expanded', 'false' );
       
    82 			}
       
    83 
       
    84 			if ( that.is( '.active' ) || $( '.search-toggle .screen-reader-text' )[0] === event.target ) {
       
    85 				wrapper.find( '.search-field' ).focus();
       
    86 			}
       
    87 		} );
       
    88 
       
    89 		/*
       
    90 		 * Fixed header for large screen.
       
    91 		 * If the header becomes more than 48px tall, unfix the header.
       
    92 		 *
       
    93 		 * The callback on the scroll event is only added if there is a header
       
    94 		 * image and we are not on mobile.
       
    95 		 */
       
    96 		if ( _window.width() > 781 ) {
       
    97 			var mastheadHeight = $( '#masthead' ).height(),
       
    98 				toolbarOffset, mastheadOffset;
       
    99 
       
   100 			if ( mastheadHeight > 48 ) {
       
   101 				body.removeClass( 'masthead-fixed' );
       
   102 			}
       
   103 
       
   104 			if ( body.is( '.header-image' ) ) {
       
   105 				toolbarOffset  = body.is( '.admin-bar' ) ? $( '#wpadminbar' ).height() : 0;
       
   106 				mastheadOffset = $( '#masthead' ).offset().top - toolbarOffset;
       
   107 
       
   108 				_window.on( 'scroll.twentyfourteen', function() {
       
   109 					if ( _window.scrollTop() > mastheadOffset && mastheadHeight < 49 ) {
       
   110 						body.addClass( 'masthead-fixed' );
       
   111 					} else {
       
   112 						body.removeClass( 'masthead-fixed' );
       
   113 					}
       
   114 				} );
       
   115 			}
       
   116 		}
       
   117 
       
   118 		// Focus styles for menus.
       
   119 		$( '.primary-navigation, .secondary-navigation' ).find( 'a' ).on( 'focus.twentyfourteen blur.twentyfourteen', function() {
       
   120 			$( this ).parents().toggleClass( 'focus' );
       
   121 		} );
       
   122 	} );
       
   123 
       
   124 	/**
       
   125 	 * Add or remove ARIA attributes.
       
   126 	 *
       
   127 	 * Uses jQuery's width() function to determine the size of the window and add
       
   128 	 * the default ARIA attributes for the menu toggle if it's visible.
       
   129 	 * @since Twenty Fourteen 1.4
       
   130 	 */
       
   131 	function onResizeARIA() {
       
   132 		if ( 781 > _window.width() ) {
       
   133 			button.attr( 'aria-expanded', 'false' );
       
   134 			menu.attr( 'aria-expanded', 'false' );
       
   135 			button.attr( 'aria-controls', 'primary-menu' );
       
   136 		} else {
       
   137 			button.removeAttr( 'aria-expanded' );
       
   138 			menu.removeAttr( 'aria-expanded' );
       
   139 			button.removeAttr( 'aria-controls' );
       
   140 		}
       
   141 	}
       
   142 
       
   143 	_window
       
   144 		.on( 'load.twentyfourteen', onResizeARIA )
       
   145 		.on( 'resize.twentyfourteen', function() {
       
   146 			onResizeARIA();
       
   147 	} );
       
   148 
       
   149 	_window.load( function() {
       
   150 		var footerSidebar,
       
   151 			isCustomizeSelectiveRefresh = ( 'undefined' !== typeof wp && wp.customize && wp.customize.selectiveRefresh );
       
   152 
       
   153 		// Arrange footer widgets vertically.
       
   154 		if ( $.isFunction( $.fn.masonry ) ) {
       
   155 			footerSidebar = $( '#footer-sidebar' );
       
   156 			footerSidebar.masonry( {
       
   157 				itemSelector: '.widget',
       
   158 				columnWidth: function( containerWidth ) {
       
   159 					return containerWidth / 4;
       
   160 				},
       
   161 				gutterWidth: 0,
       
   162 				isResizable: true,
       
   163 				isRTL: $( 'body' ).is( '.rtl' )
       
   164 			} );
       
   165 
       
   166 			if ( isCustomizeSelectiveRefresh ) {
       
   167 
       
   168 				// Retain previous masonry-brick initial position.
       
   169 				wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function( placement ) {
       
   170 					var copyPosition = (
       
   171 						placement.partial.extended( wp.customize.widgetsPreview.WidgetPartial ) &&
       
   172 						placement.removedNodes instanceof jQuery &&
       
   173 						placement.removedNodes.is( '.masonry-brick' ) &&
       
   174 						placement.container instanceof jQuery
       
   175 					);
       
   176 					if ( copyPosition ) {
       
   177 						placement.container.css( {
       
   178 							position: placement.removedNodes.css( 'position' ),
       
   179 							top: placement.removedNodes.css( 'top' ),
       
   180 							left: placement.removedNodes.css( 'left' )
       
   181 						} );
       
   182 					}
       
   183 				} );
       
   184 
       
   185 				// Re-arrange footer widgets after selective refresh event.
       
   186 				wp.customize.selectiveRefresh.bind( 'sidebar-updated', function( sidebarPartial ) {
       
   187 					if ( 'sidebar-3' === sidebarPartial.sidebarId ) {
       
   188 						footerSidebar.masonry( 'reloadItems' );
       
   189 						footerSidebar.masonry( 'layout' );
       
   190 					}
       
   191 				} );
       
   192 			}
       
   193 		}
       
   194 
       
   195 		// Initialize audio and video players in Twenty_Fourteen_Ephemera_Widget widget when selectively refreshed in Customizer.
       
   196 		if ( isCustomizeSelectiveRefresh && wp.mediaelement ) {
       
   197 			wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function() {
       
   198 				wp.mediaelement.initialize();
       
   199 			} );
       
   200 		}
       
   201 
       
   202 		// Initialize Featured Content slider.
       
   203 		if ( body.is( '.slider' ) ) {
       
   204 			$( '.featured-content' ).featuredslider( {
       
   205 				selector: '.featured-content-inner > article',
       
   206 				controlsContainer: '.featured-content'
       
   207 			} );
       
   208 		}
       
   209 	} );
       
   210 } )( jQuery );