PageSourceSearch

https://sau.edu/media/developer-assets/js/accordions/accordion.js

js sau.edu collected 2026-10-02 04:07:37 UTC 5,350 bytes, 137 lines download raw bytes

1const updateParentAccordionHeight = () => {
2    // Only apply dynamic height adjustment for mobile view
3    const isMobile = window.innerWidth <= 768;
4    if (isMobile) {
5      const parentAccordionContent = document.querySelector('.parent-accordion-content'); 
6      if (parentAccordionContent) {
7        if (parentAccordionContent.closest('[data-collapse]').classList.contains('h-0')) {
8          // Directly close the parent without calculating children height
9          parentAccordionContent.style.height = '0';
10        } else {
11          parentAccordionContent.style.height = 'auto'; // Temporarily set height to auto to calculate full height
12          const newHeight = Array.from(parentAccordionContent.children).reduce((total, child) => {
13            return total + (child.offsetHeight || 0);
14          }, 0);
15          parentAccordionContent.style.height = newHeight;
16        }
17      }
18    }
19  };
20
21const toggleAccordion = accordionButton => {
22  console.log('TA');
23  const targetID = accordionButton.getAttribute('data-collapse-target');
24  const targetContent = document.querySelector(`[data-collapse="${targetID}"]`);
25  const isOpening = targetContent.classList.contains('h-0');
26  let iconImg = accordionButton.querySelector('.icon-span img');
27  let iconSpan = iconImg ? iconImg : accordionButton.querySelector('.icon-span');
28
29  if (isOpening) {
30    targetContent.style.height = `${targetContent.scrollHeight}px`;
31    targetContent.classList.remove('h-0');
32    targetContent.classList.add('h-auto');
33    if (accordionButton.hasAttribute('data-icon-close')) {
34      if (iconImg) {
35        iconImg.src = accordionButton.getAttribute('data-icon-open');
36      } else {
37        iconSpan.textContent = accordionButton.getAttribute('data-icon-open');
38        iconSpan.classList.add('heading-3');
39      }
40    }
41  } else {
42    targetContent.style.height = '0';
43    targetContent.classList.add('h-0');
44    targetContent.classList.remove('h-auto');
45    if (accordionButton.hasAttribute('data-icon-open')) {
46      if (iconImg) {
47        iconImg.src = accordionButton.getAttribute('data-icon-close');
48      } else {
49        iconSpan.textContent = accordionButton.getAttribute('data-icon-close');
50        iconSpan.classList.add('heading-3');
51      }
52    }
53  }
54
55  if (targetContent.classList.contains('parent-accordion-content') || accordionButton.closest('.parent-accordion-content')) {
56    updateParentAccordionHeight();
57  }
58};
59
60document.addEventListener('click', event => {
61  const accordionButton = event.target.closest('[data-collapse-target]');
62  if (!accordionButton) return;
63  event.preventDefault();
64  toggleAccordion(accordionButton);
65});
66
67// Initial setup for desktop + mobile
68if (window.innerWidth > 768) {
69  setTimeout(() => {
70    const lastAccordion = document.querySelector('.accordion-l3');
71  
72  	if (lastAccordion === null) return;
73  
74    const el = lastAccordion.querySelector('[data-collapse]');
75    const accordionId = el.getAttribute('data-collapse');
76    const accordionButton = lastAccordion.querySelector(`[data-collapse-target="${accordionId}"]`);
77
78    if (!accordionButton.classList.contains('prg-acc')) {
79      el.style.height = `${el.scrollHeight}px`;
80      el.classList.remove('h-0');
81      el.classList.add('h-auto');
82    }
83  }, 750);
84}
85
86// Handle anchor links to auto-open accordions
87const handleAnchorNavigation = () => {
88  const hash = window.location.hash.substring(1); // Remove the '#'
89  
90  if (hash) {
91    // Find the anchor element
92    const anchorElement = document.getElementById(hash);
93    
94    if (anchorElement) {
95      // Find the next accordion after this anchor
96      // Look for the next sibling that has a [data-collapse] element
97      let nextElement = anchorElement.nextElementSibling;
98      let accordionContent = null;
99      
100      // Search through next siblings to find an accordion
101      while (nextElement && !accordionContent) {
102        accordionContent = nextElement.querySelector('[data-collapse]');
103        if (!accordionContent && nextElement.hasAttribute('data-collapse')) {
104          accordionContent = nextElement;
105        }
106        if (!accordionContent) {
107          nextElement = nextElement.nextElementSibling;
108        }
109      }
110      
111      // If we found an accordion and it's closed, open it
112      if (accordionContent && accordionContent.classList.contains('h-0')) {
113        const accordionId = accordionContent.getAttribute('data-collapse');
114        const accordionButton = document.querySelector(`[data-collapse-target="${accordionId}"]`);
115        
116        if (accordionButton) {
117          // Open the accordion
118          toggleAccordion(accordionButton);
119          
120          // Scroll to the anchor after accordion opens
121          setTimeout(() => {
122            anchorElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
123          }, 350);
124        }
125      } else {
126        // If no accordion found or already open, just scroll to anchor
127        anchorElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
128      }
129    }
130  }
131};
132
133// Call on page load
134window.addEventListener('load', handleAnchorNavigation);
135
136// Call when hash changes (for single-page navigation)
137window.addEventListener('hashchange', handleAnchorNavigation);

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.