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 8;(function navigation() { 9 const siteNavigation = document.getElementById('site-navigation') 10 11 // Return early if the navigation doesn't exist. 12 if (!siteNavigation) { 13 return 14 } 15 16 const button = document.getElementById('site-nav-toggle-btn') 17 const buttonContent = button.getElementsByTagName('span')[0] 18 19 // Return early if the button doesn't exist. 20 if ('undefined' === typeof button) { 21 return 22 } 23 24 const menu = siteNavigation.getElementsByTagName('ul')[0] 25 26 // Hide menu toggle button if menu is empty and return early. 27 if ('undefined' === typeof menu) { 28 button.style.display = 'none' 29 return 30 } 31 32 if (!menu.classList.contains('nav-menu')) { 33 menu.classList.add('nav-menu') 34 } 35 36 // Toggle the .toggled class and the aria-expanded value each time the button is clicked. 37 button.addEventListener('click', function() { 38 siteNavigation.classList.toggle('toggled') 39 40 if (button.getAttribute('aria-expanded') === 'true') { 41 button.setAttribute('aria-expanded', 'false') 42 } else { 43 button.setAttribute('aria-expanded', 'true') 44 } 45 }) 46 47 // Remove the .toggled class and set aria-expanded to false when the user clicks outside the navigation. 48 document.addEventListener('click', function (event) { 49 const isClickInside = 50 siteNavigation.contains(event.target) || event.target === button || button.contains(event.target) 51 52 if (button.getAttribute('aria-expanded') === 'true' && !isClickInside) { 53 siteNavigation.classList.remove('toggled') 54 button.setAttribute('aria-expanded', 'false') 55 console.log('toggle') 56 } 57 58 if ( 59 event.target.classList.contains('site-title') || 60 event.target.classList.contains('site-branding') 61 ) 62 location.href = '/' 63 }) 64 65 // Get all the link elements within the menu. 66 const links = menu.getElementsByTagName('a') 67 68 // Get all the link elements with children within the menu. 69 const linksWithChildren = menu.querySelectorAll( 70 '.menu-item-has-children > a, .page_item_has_children > a', 71 ) 72 73 // Toggle focus each time a menu link is focused or blurred. 74 for (const link of links) { 75 link.addEventListener('focus', toggleFocus, true) 76 link.addEventListener('blur', toggleFocus, true) 77 } 78 79 // Toggle focus each time a menu link with children receive a touch event. 80 for (const link of linksWithChildren) { 81 link.addEventListener('touchstart', toggleFocus, false) 82 } 83 84 /** 85 * Sets or removes .focus class on an element. 86 */ 87 function toggleFocus(event) { 88 if (event.type === 'focus' || event.type === 'blur') { 89 let self = this 90 // Move up through the ancestors of the current link until we hit .nav-menu. 91 while (!self.classList.contains('nav-menu')) { 92 // On li elements toggle the class .focus. 93 if ('li' === self.tagName.toLowerCase()) { 94 self.classList.toggle('focus') 95 } 96 self = self.parentNode 97 } 98 } 99 100 if (event.type === 'touchstart') { 101 const menuItem = this.parentNode 102 event.preventDefault() 103 for (const link of menuItem.parentNode.children) { 104 if (menuItem !== link) { 105 link.classList.remove('focus') 106 } 107 } 108 menuItem.classList.toggle('focus') 109 } 110 } 111})()
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.