navigation.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /**
  2. * File navigation.js.
  3. *
  4. * Handles toggling the navigation menu for small screens and enables TAB key
  5. * navigation support for dropdown menus.
  6. */
  7. ( function() {
  8. var container, button, menu, links, subMenus, i, len;
  9. container = document.getElementById( 'site-navigation' );
  10. if ( ! container ) {
  11. return;
  12. }
  13. button = container.getElementsByTagName( 'button' )[0];
  14. if ( 'undefined' === typeof button ) {
  15. return;
  16. }
  17. menu = container.getElementsByTagName( 'ul' )[0];
  18. // Hide menu toggle button if menu is empty and return early.
  19. if ( 'undefined' === typeof menu ) {
  20. button.style.display = 'none';
  21. return;
  22. }
  23. menu.setAttribute( 'aria-expanded', 'false' );
  24. if ( -1 === menu.className.indexOf( 'nav-menu' ) ) {
  25. menu.className += ' nav-menu';
  26. }
  27. button.onclick = function() {
  28. if ( -1 !== container.className.indexOf( 'toggled' ) ) {
  29. container.className = container.className.replace( ' toggled', '' );
  30. button.setAttribute( 'aria-expanded', 'false' );
  31. menu.setAttribute( 'aria-expanded', 'false' );
  32. } else {
  33. container.className += ' toggled';
  34. button.setAttribute( 'aria-expanded', 'true' );
  35. menu.setAttribute( 'aria-expanded', 'true' );
  36. }
  37. };
  38. // Get all the link elements within the menu.
  39. links = menu.getElementsByTagName( 'a' );
  40. subMenus = menu.getElementsByTagName( 'ul' );
  41. // Each time a menu link is focused or blurred, toggle focus.
  42. for ( i = 0, len = links.length; i < len; i++ ) {
  43. links[i].addEventListener( 'focus', toggleFocus, true );
  44. links[i].addEventListener( 'blur', toggleFocus, true );
  45. }
  46. /**
  47. * Sets or removes .focus class on an element.
  48. */
  49. function toggleFocus() {
  50. var self = this;
  51. // Move up through the ancestors of the current link until we hit .nav-menu.
  52. while ( -1 === self.className.indexOf( 'nav-menu' ) ) {
  53. // On li elements toggle the class .focus.
  54. if ( 'li' === self.tagName.toLowerCase() ) {
  55. if ( -1 !== self.className.indexOf( 'focus' ) ) {
  56. self.className = self.className.replace( ' focus', '' );
  57. } else {
  58. self.className += ' focus';
  59. }
  60. }
  61. self = self.parentElement;
  62. }
  63. }
  64. /**
  65. * Toggles `focus` class to allow submenu access on tablets.
  66. */
  67. ( function( container ) {
  68. var touchStartFn, i,
  69. parentLink = container.querySelectorAll( '.menu-item-has-children > a, .page_item_has_children > a' );
  70. if ( 'ontouchstart' in window ) {
  71. touchStartFn = function( e ) {
  72. var menuItem = this.parentNode, i;
  73. if ( ! menuItem.classList.contains( 'focus' ) ) {
  74. e.preventDefault();
  75. for ( i = 0; i < menuItem.parentNode.children.length; ++i ) {
  76. if ( menuItem === menuItem.parentNode.children[i] ) {
  77. continue;
  78. }
  79. menuItem.parentNode.children[i].classList.remove( 'focus' );
  80. }
  81. menuItem.classList.add( 'focus' );
  82. } else {
  83. menuItem.classList.remove( 'focus' );
  84. }
  85. };
  86. for ( i = 0; i < parentLink.length; ++i ) {
  87. parentLink[i].addEventListener( 'touchstart', touchStartFn, false );
  88. }
  89. }
  90. }( container ) );
  91. } )();