functions.js 5.1 KB

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