navigation.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /* global photosScreenReaderText */
  2. ( function( $ ) {
  3. var body, header, menuToggle, siteNavContain, siteNavigation, siteBranding, resizeTimer;
  4. header = $( '#masthead' );
  5. menuToggle = header.find( '.menu-toggle' );
  6. siteNavigation = header.find( '.main-navigation' );
  7. siteBranding = header.find( '.site-branding' );
  8. // Enable menuToggle.
  9. ( function() {
  10. // Return early if menuToggle is missing.
  11. if ( ! menuToggle.length ) {
  12. return;
  13. }
  14. // Add an initial value for the attribute.
  15. menuToggle.attr( 'aria-expanded', 'false' );
  16. menuToggle.on( 'click', function() {
  17. $( this ).toggleClass( 'toggled-on' );
  18. header.toggleClass( 'overlay' );
  19. siteNavigation.toggleClass( 'toggled-on' );
  20. $( this ).attr( 'aria-expanded', siteNavigation.hasClass( 'toggled-on' ) );
  21. } );
  22. } )();
  23. // Checks if the action bar is visible at the bottom of the screen
  24. checkactionbar = function() {
  25. if ( 'none' == menuToggle.css( 'display' ) ) return;
  26. if ( $( '#actionbar' ).length ){
  27. if ( ! $( '#actionbar' ).hasClass( 'actnbr-hidden' ) ) {
  28. menuToggle.addClass( 'actnbr-visible' );
  29. } else {
  30. menuToggle.removeClass( 'actnbr-visible' );
  31. }
  32. }
  33. };
  34. setInterval( checkactionbar, 200 );
  35. // Fix sub-menus for touch devices and better focus for hidden submenu items for accessibility.
  36. ( function() {
  37. if ( ! siteNavigation.length || ! siteNavigation.children().length ) {
  38. return;
  39. }
  40. // Toggle `focus` class to allow submenu access on tablets.
  41. function toggleFocusClassTouchScreen() {
  42. if ( 'none' === $( '.menu-toggle' ).css( 'display' ) ) {
  43. $( document.body ).on( 'touchstart', function( e ) {
  44. if ( ! $( e.target ).closest( '.main-navigation li' ).length ) {
  45. $( '.main-navigation li' ).removeClass( 'focus' );
  46. }
  47. } );
  48. siteNavigation.find( '.menu-item-has-children > a, .page_item_has_children > a, .menu-item.site-header-cart > a' )
  49. .on( 'touchstart', function( e ) {
  50. var el = $( this ).parent( 'li' );
  51. if ( ! el.hasClass( 'focus' ) ) {
  52. e.preventDefault();
  53. el.toggleClass( 'focus' );
  54. el.siblings( '.focus' ).removeClass( 'focus' );
  55. }
  56. } );
  57. } else {
  58. siteNavigation.find( '.menu-item-has-children > a, .page_item_has_children > a, .menu-item.site-header-cart > a' ).unbind( 'touchstart' );
  59. }
  60. }
  61. if ( 'ontouchstart' in window ) {
  62. $( window ).on( 'resize', toggleFocusClassTouchScreen );
  63. toggleFocusClassTouchScreen();
  64. }
  65. siteNavigation.find( 'a' ).on( 'focus blur', function() {
  66. $( this ).parents( '.menu-item, .page_item' ).toggleClass( 'focus' );
  67. } );
  68. } )();
  69. // Initiate navigation.
  70. function initMainNavigation( container ) {
  71. // Add dropdown toggle that displays child menu items.
  72. var dropdownToggle = $( '<button />', { 'class': 'dropdown-toggle', 'aria-expanded': false })
  73. .append( photosScreenReaderText.icon )
  74. .append( $( '<span />', { 'class': 'screen-reader-text', text: photosScreenReaderText.expand } ) );
  75. container.find( '.menu-item-has-children > a, .page_item_has_children > a' ).after( dropdownToggle );
  76. // Set the active submenu dropdown toggle button initial state.
  77. container.find( '.current-menu-ancestor > button' )
  78. .addClass( 'toggled-on' )
  79. .attr( 'aria-expanded', 'true' )
  80. .find( '.screen-reader-text' )
  81. .text( photosScreenReaderText.collapse );
  82. // Set the active submenu initial state.
  83. container.find( '.current-menu-ancestor > .sub-menu' ).addClass( 'toggled-on' );
  84. container.find( '.dropdown-toggle' ).click( function( e ) {
  85. var _this = $( this ),
  86. screenReaderSpan = _this.find( '.screen-reader-text' );
  87. e.preventDefault();
  88. _this.toggleClass( 'toggled-on' );
  89. _this.next( '.children, .sub-menu' ).toggleClass( 'toggled-on' );
  90. _this.attr( 'aria-expanded', _this.attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' );
  91. screenReaderSpan.text( screenReaderSpan.text() === photosScreenReaderText.expand ? photosScreenReaderText.collapse : photosScreenReaderText.expand );
  92. } );
  93. }
  94. // Change dropdown direction depending on the width.
  95. function dropdownDirection() {
  96. var innerHeader = siteNavigation.outerWidth() + siteBranding.outerWidth();
  97. if ( innerHeader <= header.width() ) {
  98. body.addClass( 'menu-direction-left' );
  99. } else {
  100. body.removeClass( 'menu-direction-left' );
  101. }
  102. }
  103. $( document ).ready( function() {
  104. body = $( document.body );
  105. $( window )
  106. .on( 'load', function() {
  107. initMainNavigation( $( '.main-navigation' ) );
  108. dropdownDirection();
  109. } )
  110. .on( 'resize', function() {
  111. clearTimeout( resizeTimer );
  112. resizeTimer = setTimeout( function() {
  113. dropdownDirection();
  114. }, 500 );
  115. } );
  116. } );
  117. $( document ).on( 'customize-preview-menu-refreshed', function( e, params ) {
  118. if ( 'menu-1' === params.wpNavMenuArgs.theme_location ) {
  119. $( document.body ).resize();
  120. }
  121. } );
  122. } )( jQuery );