functions.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* global screenReaderText */
  2. /**
  3. * Theme functions file.
  4. *
  5. * Contains handlers for navigation and widget area.
  6. */
  7. ( function( $ ) {
  8. var $body, $window, $sidebar, adminbarOffset, top = false,
  9. bottom = false, windowWidth, windowHeight, lastWindowPos = 0,
  10. topOffset = 0, bodyHeight, sidebarHeight, resizeTimer,
  11. secondary, button;
  12. function initMainNavigation( container ) {
  13. // Add dropdown toggle that display child menu items.
  14. container.find( '.menu-item-has-children > a' ).after( '<button class="dropdown-toggle" aria-expanded="false">' + screenReaderText.expand + '</button>' );
  15. // Toggle buttons and submenu items with active children menu items.
  16. container.find( '.current-menu-ancestor > button' ).addClass( 'toggle-on' );
  17. container.find( '.current-menu-ancestor > .sub-menu' ).addClass( 'toggled-on' );
  18. container.find( '.dropdown-toggle' ).click( function( e ) {
  19. var _this = $( this );
  20. e.preventDefault();
  21. _this.toggleClass( 'toggle-on' );
  22. _this.next( '.children, .sub-menu' ).toggleClass( 'toggled-on' );
  23. _this.attr( 'aria-expanded', _this.attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' );
  24. _this.html( _this.html() === screenReaderText.expand ? screenReaderText.collapse : screenReaderText.expand );
  25. } );
  26. }
  27. initMainNavigation( $( '.main-navigation' ) );
  28. // Re-initialize the main navigation when it is updated, persisting any existing submenu expanded states.
  29. $( document ).on( 'customize-preview-menu-refreshed', function( e, params ) {
  30. if ( 'primary' === params.wpNavMenuArgs.theme_location ) {
  31. initMainNavigation( params.newContainer );
  32. // Re-sync expanded states from oldContainer.
  33. params.oldContainer.find( '.dropdown-toggle.toggle-on' ).each(function() {
  34. var containerId = $( this ).parent().prop( 'id' );
  35. $( params.newContainer ).find( '#' + containerId + ' > .dropdown-toggle' ).triggerHandler( 'click' );
  36. });
  37. }
  38. });
  39. secondary = $( '#secondary' );
  40. button = $( '.site-branding' ).find( '.secondary-toggle' );
  41. // Enable menu toggle for small screens.
  42. ( function() {
  43. var menu, widgets, social;
  44. if ( ! secondary || ! button ) {
  45. return;
  46. }
  47. // Hide button if there are no widgets and the menus are missing or empty.
  48. menu = secondary.find( '.nav-menu' );
  49. widgets = secondary.find( '#widget-area' );
  50. social = secondary.find( '#social-navigation' );
  51. if ( ! widgets.length && ! social.length && ( ! menu || ! menu.children().length ) ) {
  52. button.hide();
  53. return;
  54. }
  55. button.on( 'click.twentyfifteen', function() {
  56. secondary.toggleClass( 'toggled-on' );
  57. secondary.trigger( 'resize' );
  58. $( this ).toggleClass( 'toggled-on' );
  59. if ( $( this, secondary ).hasClass( 'toggled-on' ) ) {
  60. $( this ).attr( 'aria-expanded', 'true' );
  61. secondary.attr( 'aria-expanded', 'true' );
  62. } else {
  63. $( this ).attr( 'aria-expanded', 'false' );
  64. secondary.attr( 'aria-expanded', 'false' );
  65. }
  66. } );
  67. } )();
  68. /**
  69. * @summary Add or remove ARIA attributes.
  70. * Uses jQuery's width() function to determine the size of the window and add
  71. * the default ARIA attributes for the menu toggle if it's visible.
  72. * @since Twenty Fifteen 1.1
  73. */
  74. function onResizeARIA() {
  75. if ( 955 > $window.width() ) {
  76. button.attr( 'aria-expanded', 'false' );
  77. secondary.attr( 'aria-expanded', 'false' );
  78. button.attr( 'aria-controls', 'secondary' );
  79. } else {
  80. button.removeAttr( 'aria-expanded' );
  81. secondary.removeAttr( 'aria-expanded' );
  82. button.removeAttr( 'aria-controls' );
  83. }
  84. }
  85. // Sidebar scrolling.
  86. function resize() {
  87. windowWidth = $window.width();
  88. if ( 955 > windowWidth ) {
  89. top = bottom = false;
  90. $sidebar.removeAttr( 'style' );
  91. }
  92. }
  93. function scroll() {
  94. var windowPos = $window.scrollTop();
  95. if ( 955 > windowWidth ) {
  96. return;
  97. }
  98. sidebarHeight = $sidebar.height();
  99. windowHeight = $window.height();
  100. bodyHeight = $body.height();
  101. if ( sidebarHeight + adminbarOffset > windowHeight ) {
  102. if ( windowPos > lastWindowPos ) {
  103. if ( top ) {
  104. top = false;
  105. topOffset = ( $sidebar.offset().top > 0 ) ? $sidebar.offset().top - adminbarOffset : 0;
  106. $sidebar.attr( 'style', 'top: ' + topOffset + 'px;' );
  107. } else if ( ! bottom && windowPos + windowHeight > sidebarHeight + $sidebar.offset().top && sidebarHeight + adminbarOffset < bodyHeight ) {
  108. bottom = true;
  109. $sidebar.attr( 'style', 'position: fixed; bottom: 0;' );
  110. }
  111. } else if ( windowPos < lastWindowPos ) {
  112. if ( bottom ) {
  113. bottom = false;
  114. topOffset = ( $sidebar.offset().top > 0 ) ? $sidebar.offset().top - adminbarOffset : 0;
  115. $sidebar.attr( 'style', 'top: ' + topOffset + 'px;' );
  116. } else if ( ! top && windowPos + adminbarOffset < $sidebar.offset().top ) {
  117. top = true;
  118. $sidebar.attr( 'style', 'position: fixed;' );
  119. }
  120. } else {
  121. top = bottom = false;
  122. topOffset = ( $sidebar.offset().top > 0 ) ? $sidebar.offset().top - adminbarOffset : 0;
  123. $sidebar.attr( 'style', 'top: ' + topOffset + 'px;' );
  124. }
  125. } else if ( ! top ) {
  126. top = true;
  127. $sidebar.attr( 'style', 'position: fixed;' );
  128. }
  129. lastWindowPos = windowPos;
  130. }
  131. function resizeAndScroll() {
  132. resize();
  133. scroll();
  134. }
  135. $( document ).ready( function() {
  136. $body = $( document.body );
  137. $window = $( window );
  138. $sidebar = $( '#sidebar' ).first();
  139. adminbarOffset = $body.is( '.admin-bar' ) ? $( '#wpadminbar' ).height() : 0;
  140. $window
  141. .on( 'scroll.twentyfifteen', scroll )
  142. .on( 'load.twentyfifteen', onResizeARIA )
  143. .on( 'resize.twentyfifteen', function() {
  144. clearTimeout( resizeTimer );
  145. resizeTimer = setTimeout( resizeAndScroll, 500 );
  146. onResizeARIA();
  147. } );
  148. $sidebar.on( 'click.twentyfifteen keydown.twentyfifteen', 'button', resizeAndScroll );
  149. resizeAndScroll();
  150. for ( var i = 1; i < 6; i++ ) {
  151. setTimeout( resizeAndScroll, 100 * i );
  152. }
  153. } );
  154. } )( jQuery );