primary-navigation.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**
  2. * File primary-navigation.js.
  3. *
  4. * Required to open and close the mobile navigation.
  5. */
  6. ( function () {
  7. /**
  8. * Menu Toggle Behaviors
  9. *
  10. * @param {Element} element
  11. */
  12. var navMenu = function ( id ) {
  13. var wrapper = document.body; // this is the element to which a CSS class is added when a mobile nav menu is open
  14. var openButton = document.getElementById( id + '-open-menu' );
  15. var closeButton = document.getElementById( id + '-close-menu' );
  16. if ( openButton && closeButton ) {
  17. openButton.onclick = function () {
  18. wrapper.classList.add( id + '-navigation-open' );
  19. wrapper.classList.add( 'lock-scrolling' );
  20. closeButton.focus();
  21. };
  22. closeButton.onclick = function () {
  23. wrapper.classList.remove( id + '-navigation-open' );
  24. wrapper.classList.remove( 'lock-scrolling' );
  25. openButton.focus();
  26. };
  27. }
  28. document.addEventListener( 'click', function( event ) {
  29. // If target onclick is <a> with # within the href attribute
  30. if ( event.target.hash && event.target.hash.includes( '#' ) ) {
  31. wrapper.classList.remove( id + '-navigation-open' );
  32. wrapper.classList.remove( 'lock-scrolling' );
  33. // Wait 550 and scroll to the anchor.
  34. setTimeout(function () {
  35. var anchor = document.getElementById(event.target.hash.slice(1));
  36. anchor.scrollIntoView();
  37. }, 550);
  38. }
  39. } );
  40. /**
  41. * Trap keyboard navigation in the menu modal.
  42. * Adapted from TwentyTwenty
  43. */
  44. document.addEventListener( 'keydown', function ( event ) {
  45. if ( ! wrapper.classList.contains( id + '-navigation-open' ) ) {
  46. return;
  47. }
  48. var modal,
  49. elements,
  50. selectors,
  51. lastEl,
  52. firstEl,
  53. activeEl,
  54. tabKey,
  55. shiftKey,
  56. escKey;
  57. modal = document.querySelector( '.' + id + '-navigation' );
  58. selectors = 'input, a, button';
  59. elements = modal.querySelectorAll( selectors );
  60. elements = Array.prototype.slice.call( elements );
  61. elements = elements.filter( function ( el ) {
  62. return ! el.classList.contains( 'woocommerce-cart-link' ); // ignore this element because it's hidden on mobile
  63. } );
  64. tabKey = event.keyCode === 9;
  65. shiftKey = event.shiftKey;
  66. escKey = event.keyCode === 27;
  67. activeEl = document.activeElement;
  68. lastEl = elements[ elements.length - 1 ];
  69. firstEl = elements[ 0 ];
  70. if ( escKey ) {
  71. event.preventDefault();
  72. wrapper.classList.remove(
  73. id + '-navigation-open',
  74. 'lock-scrolling'
  75. );
  76. openButton.focus();
  77. }
  78. if ( ! shiftKey && tabKey && lastEl === activeEl ) {
  79. event.preventDefault();
  80. firstEl.focus();
  81. }
  82. if ( shiftKey && tabKey && firstEl === activeEl ) {
  83. event.preventDefault();
  84. lastEl.focus();
  85. }
  86. // If there are no elements in the menu, don't move the focus
  87. if ( tabKey && firstEl === lastEl ) {
  88. event.preventDefault();
  89. }
  90. } );
  91. };
  92. window.addEventListener( 'load', function () {
  93. new navMenu( 'primary' );
  94. new navMenu( 'woo' );
  95. } );
  96. } )();