PageSourceSearch

https://home.treasury.gov/js/treasury.js

js treasury.gov collected 2026-09-24 06:06:52 UTC 8,691 bytes, 276 lines download raw bytes

1/**
2 * U.S. Department of the Treasury
3 * Site JavaScript
4 */
5
6(function() {
7  'use strict';
8
9  // ============================================
10  // Sticky Nav - Show logo when scrolled
11  // ============================================
12  const mainNav = document.querySelector('.treas-main-nav');
13  const header = document.getElementById('header');
14  
15  if (mainNav && header) {
16    function handleScroll() {
17      const headerBottom = header.offsetTop + header.offsetHeight;
18      if (window.scrollY >= headerBottom) {
19        mainNav.classList.add('scrolled');
20      } else {
21        mainNav.classList.remove('scrolled');
22      }
23    }
24    
25    window.addEventListener('scroll', handleScroll, { passive: true });
26    handleScroll(); // Check on load
27  }
28
29  // ============================================
30  // USA Banner toggle
31  // ============================================
32  const bannerButton = document.querySelector('.usa-banner-button');
33  const bannerContent = document.getElementById('gov-banner-content');
34  
35  if (bannerButton && bannerContent) {
36    bannerButton.addEventListener('click', function() {
37      const expanded = this.getAttribute('aria-expanded') === 'true';
38      this.setAttribute('aria-expanded', !expanded);
39      bannerContent.hidden = expanded;
40    });
41  }
42
43  // ============================================
44  // Mega Menu Navigation (Click to Open)
45  // ============================================
46  const megaMenuButtons = document.querySelectorAll('.treas-main-nav__list-item.has-dropdown > button.nav-link');
47  let activeMegaMenu = null;
48  
49  function closeAllMegaMenus() {
50    megaMenuButtons.forEach(btn => {
51      btn.setAttribute('aria-expanded', 'false');
52    });
53    activeMegaMenu = null;
54  }
55  
56  megaMenuButtons.forEach(btn => {
57    btn.addEventListener('click', function(e) {
58      e.preventDefault();
59      e.stopPropagation();
60      
61      const isExpanded = this.getAttribute('aria-expanded') === 'true';
62      const parentItem = this.closest('.treas-main-nav__list-item');
63      
64      // Close all menus first
65      closeAllMegaMenus();
66      closeSearchDropdown();
67      
68      // Toggle this menu (open if was closed)
69      if (!isExpanded) {
70        this.setAttribute('aria-expanded', 'true');
71        activeMegaMenu = parentItem;
72      }
73    });
74  });
75  
76  // Close mega menus when clicking outside
77  document.addEventListener('click', function(e) {
78    if (activeMegaMenu && !e.target.closest('.treas-main-nav__list-item.has-dropdown') && !e.target.closest('.mega-menu')) {
79      closeAllMegaMenus();
80    }
81  });
82  
83  // Close mega menus when clicking inside mega menu links
84  document.querySelectorAll('.mega-menu a').forEach(link => {
85    link.addEventListener('click', function() {
86      closeAllMegaMenus();
87    });
88  });
89
90  // ============================================
91  // Search Dropdown
92  // ============================================
93  const searchToggle = document.querySelector('.search-toggle');
94  const searchDropdown = document.getElementById('search-dropdown');
95  
96  function closeSearchDropdown() {
97    if (searchDropdown) {
98      searchDropdown.hidden = true;
99      searchToggle?.setAttribute('aria-expanded', 'false');
100    }
101  }
102  
103  function openSearchDropdown() {
104    if (searchDropdown) {
105      searchDropdown.hidden = false;
106      searchToggle?.setAttribute('aria-expanded', 'true');
107      const input = searchDropdown.querySelector('.search-input');
108      if (input) input.focus();
109    }
110  }
111  
112  if (searchToggle) {
113    searchToggle.addEventListener('click', function(e) {
114      e.preventDefault();
115      e.stopPropagation();
116      
117      const isExpanded = this.getAttribute('aria-expanded') === 'true';
118      
119      // Close mega menus
120      closeAllMegaMenus();
121      
122      // Toggle search
123      if (isExpanded) {
124        closeSearchDropdown();
125      } else {
126        openSearchDropdown();
127      }
128    });
129  }
130  
131  // Close search when clicking outside
132  document.addEventListener('click', function(e) {
133    if (searchDropdown && !searchDropdown.hidden && !e.target.closest('.nav-search')) {
134      closeSearchDropdown();
135    }
136  });
137  
138  // Close all on Escape and return focus to trigger
139  document.addEventListener('keydown', function(e) {
140    if (e.key === 'Escape') {
141      // Return focus to active mega menu button if one was open
142      if (activeMegaMenu) {
143        const triggerBtn = activeMegaMenu.querySelector('button.nav-link');
144        closeAllMegaMenus();
145        if (triggerBtn) triggerBtn.focus();
146      }
147      // Return focus to search toggle if search was open
148      if (searchDropdown && !searchDropdown.hidden) {
149        closeSearchDropdown();
150        if (searchToggle) searchToggle.focus();
151      }
152    }
153  });
154
155  // ============================================
156  // Hero Slider
157  // ============================================
158  const slides = document.querySelectorAll('.hero-slide');
159  const dots = document.querySelectorAll('.slider-dot');
160  let currentSlide = 0;
161  let slideInterval;
162  
163  function showSlide(index) {
164    slides.forEach((slide, i) => {
165      slide.classList.toggle('active', i === index);
166    });
167    dots.forEach((dot, i) => {
168      dot.classList.toggle('active', i === index);
169    });
170    currentSlide = index;
171  }
172  
173  function nextSlide() {
174    const next = (currentSlide + 1) % slides.length;
175    showSlide(next);
176  }
177  
178  if (slides.length > 1) {
179    // Auto-advance slides every 6 seconds
180    slideInterval = setInterval(nextSlide, 6000);
181    
182    // Dot click handlers
183    dots.forEach((dot, i) => {
184      dot.addEventListener('click', () => {
185        clearInterval(slideInterval);
186        showSlide(i);
187        slideInterval = setInterval(nextSlide, 6000);
188      });
189    });
190  }
191
192  // ============================================
193  // Mobile menu toggle
194  // ============================================
195  const mobileToggle = document.querySelector('.mobile-menu-toggle');
196  const navMenu = document.querySelector('.treas-main-nav__list');
197  
198  if (mobileToggle && navMenu) {
199    mobileToggle.addEventListener('click', function() {
200      const expanded = this.getAttribute('aria-expanded') === 'true';
201      this.setAttribute('aria-expanded', !expanded);
202      navMenu.classList.toggle('is-open');
203      document.body.classList.toggle('menu-open');
204    });
205  }
206
207  // ============================================
208  // Careers nav + hover menu
209  // ============================================
210  const careersBurger = document.querySelector('.careers-burger');
211  const careersNavigation = document.querySelector('.careers-navigation');
212  const careersNavMenu = document.getElementById('careers-nav-menu');
213
214  if (careersBurger && careersNavigation && careersNavMenu) {
215    careersBurger.addEventListener('click', function() {
216      const expanded = this.getAttribute('aria-expanded') === 'true';
217      this.setAttribute('aria-expanded', String(!expanded));
218      this.classList.toggle('is-expanded', !expanded);
219      careersNavigation.classList.toggle('careers-nav-open', !expanded);
220    });
221  }
222
223  const hoverContainers = document.querySelectorAll('.chco-hover-container');
224
225  function closeCareersHoverMenus() {
226    hoverContainers.forEach(container => {
227      container.classList.remove('is-open');
228      const trigger = container.querySelector('.chco-hover-trigger');
229      if (trigger) {
230        trigger.setAttribute('aria-expanded', 'false');
231      }
232    });
233  }
234
235  hoverContainers.forEach(container => {
236    const trigger = container.querySelector('.chco-hover-trigger');
237    if (!trigger) return;
238
239    trigger.addEventListener('click', function(e) {
240      e.preventDefault();
241      const isOpen = container.classList.contains('is-open');
242      closeCareersHoverMenus();
243      if (!isOpen) {
244        container.classList.add('is-open');
245        trigger.setAttribute('aria-expanded', 'true');
246      }
247    });
248
249    container.addEventListener('mouseleave', function() {
250      if (window.innerWidth >= 1025) {
251        container.classList.remove('is-open');
252        trigger.setAttribute('aria-expanded', 'false');
253      }
254    });
255  });
256
257  document.addEventListener('click', function(e) {
258    if (!e.target.closest('.chco-hover-container')) {
259      closeCareersHoverMenus();
260    }
261  });
262
263  document.addEventListener('keydown', function(e) {
264    if (e.key === 'Escape') {
265      closeCareersHoverMenus();
266    }
267  });
268
269  // ============================================
270  // News Filter - Submits to live Treasury site
271  // ============================================
272  // Form action is set in the HTML template to submit to
273  // https://home.treasury.gov/news/press-releases/ (or current section)
274  // No client-side interception needed.
275
276})();

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.