PageSourceSearch

https://sau.edu/media/developer-assets/js/navigation/mobile-nav-submenus.js

js sau.edu collected 2026-10-02 04:06:55 UTC 4,339 bytes, 129 lines download raw bytes

1/* Mobile menu fixes start */
2document.addEventListener("DOMContentLoaded", () => {
3  const menuToggle = document.getElementById("menuToggle");
4  const mobileNav = document.getElementById("mobile-nav-container");
5  const horiScroll = document.getElementById("mobile-nav-horizontal-scroll-button-container");
6  const hamburgerIcon = document.getElementById("hamburgerIcon");
7  const closeIcon = document.getElementById("closeIcon");
8
9  if (!menuToggle || !mobileNav) return;
10
11  menuToggle.setAttribute("type", "button");
12  menuToggle.setAttribute("aria-controls", "mobile-nav-container");
13
14  let suppressClickUntil = 0;
15
16  const setOpenState = (isOpen) => {
17    mobileNav.classList.toggle("hide", !isOpen);
18    if (horiScroll) horiScroll.classList.toggle("hidden", !isOpen);
19    if (hamburgerIcon) hamburgerIcon.classList.toggle("hidden", isOpen);
20    if (closeIcon) closeIcon.classList.toggle("hidden", !isOpen);
21    menuToggle.classList.toggle("menu-toggle--is-active", isOpen);
22    menuToggle.setAttribute("aria-expanded", String(isOpen));
23    document.body.style.overflow = isOpen ? "hidden" : "";
24  };
25
26  const getOpenState = () => !mobileNav.classList.contains("hide");
27
28  setOpenState(getOpenState());
29
30  menuToggle.addEventListener(
31    "pointerup",
32    (e) => {
33      e.preventDefault();
34      e.stopPropagation();
35      e.stopImmediatePropagation();
36
37      const nextOpen = !getOpenState();
38      setOpenState(nextOpen);
39
40      suppressClickUntil = performance.now() + 700;
41    },
42    true
43  );
44
45  menuToggle.addEventListener(
46    "click",
47    (e) => {
48      if (performance.now() < suppressClickUntil) {
49        e.preventDefault();
50        e.stopPropagation();
51        e.stopImmediatePropagation();
52      }
53    },
54    true
55  );
56});
57/* Mobile menu fixes end */
58
59
60
61// PC > Mac 
62
63let navList = [];
64
65document.addEventListener('DOMContentLoaded', () => {
66                          
67   	const isWithinAcademicPrograms = (element) => {
68        // Traverse up to find if any parent menu item is "Academic Programs"
69        let currentElement = element;
70        while (currentElement && !currentElement.matches('.bottom-nav')) {
71            if (currentElement.matches('.top-level') && currentElement.querySelector('a').textContent.trim() === "Academic Programs") {
72                return true;
73            }
74            currentElement = currentElement.parentElement;
75        }
76        return false;
77    };
78
79    const backButtons = document.getElementsByClassName('backButton');
80
81    const academicProgramsLi = Array.from(document.querySelectorAll('.mobile-nav .top-level'))
82        .find(li => li.querySelector('a').textContent.trim() === "Academic Programs");
83
84    const toggleSubmenuVisibility = (submenu, withinAcademicPrograms, event) => {
85      
86      if(withinAcademicPrograms || submenu.classList.contains("multilevel-linkul-0") ){
87        event.preventDefault();
88        submenu.classList.toggle('active');
89        navList.push(submenu);
90      }
91      
92    };
93
94    document.querySelector('.mobile-nav').addEventListener('click', (event) => {
95        const { target } = event;
96        if (target.matches('.mobile-nav a')) {
97            const submenu = target.nextElementSibling;
98          	
99            if (submenu && submenu.matches('[class^="multilevel-linkul-"]')) {
100                //event.preventDefault();
101
102                const withinAcademicPrograms = academicProgramsLi.contains(target);
103                toggleSubmenuVisibility(submenu, withinAcademicPrograms, event);
104            }
105        }
106
107    });
108
109    document.addEventListener('click', (event) => {
110        if (!event.target.closest('.mobile-nav')) {
111            // Hide all submenus
112            document.querySelectorAll('.mobile-nav [class^="multilevel-linkul-"].active').forEach(submenu => {
113                submenu.classList.remove('active');
114            });
115        }
116    });
117
118    for (let i = 0; i < backButtons.length; i++) {
119      backButtons[i].addEventListener('click', () => {
120          currentNav = navList.pop();
121          if (currentNav) {
122              currentNav.classList.remove('active');
123              currentNav.style.display = 'none';
124              currentNav.classList.add('hidden');
125          }
126      });
127  }
128  
129});

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.