navigation.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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 masthead, menuToggle, siteNavContain, siteNavigation;
  9. function initMainNavigation( container ) {
  10. // Add dropdown toggle that displays child menu items.
  11. var dropdownToggle = $( '<button />', { 'class': 'dropdown-toggle', 'aria-expanded': false } )
  12. .append( screenReaderText.icon_expand )
  13. .append( $( '<span />', { 'class': 'screen-reader-text', text: screenReaderText.expand } ) );
  14. container.find( '.menu-item-has-children > a, .page_item_has_children > a' ).after( dropdownToggle );
  15. // Set the active submenu dropdown toggle button initial state.
  16. container.find( '.current-menu-ancestor > button' )
  17. .addClass( 'toggled' )
  18. .attr( 'aria-expanded', 'true' )
  19. .find( '.screen-reader-text' )
  20. .text( screenReaderText.collapse );
  21. // Set the active submenu initial state.
  22. container.find( '.current-menu-ancestor > .sub-menu' ).addClass( 'toggled' );
  23. container.find( '.dropdown-toggle' ).click( function( e ) {
  24. var _this = $( this ),
  25. screenReaderSpan = _this.find( '.screen-reader-text' );
  26. e.preventDefault();
  27. _this.toggleClass( 'toggled' );
  28. _this.next( '.children, .sub-menu' ).toggleClass( 'toggled' );
  29. _this.attr( 'aria-expanded', _this.attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' );
  30. screenReaderSpan.text( screenReaderSpan.text() === screenReaderText.expand ? screenReaderText.collapse : screenReaderText.expand );
  31. });
  32. }
  33. initMainNavigation( $( '.main-navigation' ) );
  34. masthead = $( '#masthead' );
  35. menuToggle = masthead.find( '.menu-toggle' );
  36. siteNavContain = masthead.find( '.main-navigation' );
  37. siteNavigation = masthead.find( '.main-navigation > div > ul' );
  38. // Enable menuToggle.
  39. ( function() {
  40. // Return early if menuToggle is missing.
  41. if ( ! menuToggle.length ) {
  42. return;
  43. }
  44. // Add an initial value for the attribute.
  45. menuToggle.attr( 'aria-expanded', 'false' );
  46. menuToggle.on( 'click.radcliffe_2', function() {
  47. siteNavContain.toggleClass( 'toggled' );
  48. $( this ).attr( 'aria-expanded', siteNavContain.hasClass( 'toggled' ) );
  49. } );
  50. } )();
  51. // Fix sub-menus for touch devices and better focus for hidden submenu items for accessibility.
  52. ( function() {
  53. if ( ! siteNavigation.length || ! siteNavigation.children().length ) {
  54. return;
  55. }
  56. // Toggle `focus` class to allow submenu access on tablets.
  57. function toggleFocusClassTouchScreen() {
  58. if ( 'none' === $( '.menu-toggle' ).css( 'display' ) ) {
  59. $( document.body ).on( 'touchstart.radcliffe_2', function( e ) {
  60. if ( ! $( e.target ).closest( '.main-navigation li' ).length ) {
  61. $( '.main-navigation li' ).removeClass( 'focus' );
  62. }
  63. } );
  64. siteNavigation.find( '.menu-item-has-children > a, .page_item_has_children > a' )
  65. .on( 'touchstart.radcliffe_2', function( e ) {
  66. var el = $( this ).parent( 'li' );
  67. if ( ! el.hasClass( 'focus' ) ) {
  68. e.preventDefault();
  69. el.toggleClass( 'focus' );
  70. el.siblings( '.focus' ).removeClass( 'focus' );
  71. }
  72. } );
  73. } else {
  74. siteNavigation.find( '.menu-item-has-children > a, .page_item_has_children > a' ).unbind( 'touchstart.radcliffe_2' );
  75. }
  76. }
  77. if ( 'ontouchstart' in window ) {
  78. $( window ).on( 'resize.radcliffe_2', toggleFocusClassTouchScreen );
  79. toggleFocusClassTouchScreen();
  80. }
  81. siteNavigation.find( 'a' ).on( 'focus.radcliffe_2 blur.radcliffe_2', function() {
  82. $( this ).parents( '.menu-item, .page_item' ).toggleClass( 'focus' );
  83. } );
  84. } )();
  85. } )( jQuery );