PageSourceSearch

https://www.exact.com/media/templates/site/pwttemplate/js/navigation.js?00a3c3

js exact.com collected 2026-09-24 08:28:21 UTC 5,590 bytes, 183 lines download raw bytes

1/* eslint-disable */
2
3// Main navigation script
4(() => {
5  // Variables
6  let navTimeout = false;
7
8  // Selectors
9  const searchWrapperClass = '.search-wrapper'; // Used in variable and in 'closest()'
10  const headerNavigationClass = '.header__navigation'; // Used in variable and in 'closest()'
11  const navigationList = document.querySelector('.navigation__list');
12  const searchToggle = document.querySelector('.search-toggle');
13  const searchWrapper = document.querySelector(searchWrapperClass);
14  const search = document.querySelector('#search');
15  const searchCancel = document.querySelector('.search__cancel');
16  const searchSubmit = document.querySelector('.search__submit');
17  const navigationToggle = document.querySelector('.navigation-toggle');
18  const searchVisibleClass = 'search:visible';
19  const navigationVisibleClass = 'navigation:visible';
20  const hiddenMobileClass = 'hidden:mobile';
21
22  // console.log(searchWrapperClass);
23  // console.log(headerNavigationClass);
24  // console.log(navigationList);
25  // console.log(searchToggle);
26  // console.log(searchWrapper);
27  // console.log(search);
28  // console.log(searchCancel);
29  // console.log(searchSubmit);
30  // console.log(navigationToggle);
31  // console.log(searchVisibleClass);
32  // console.log(navigationVisibleClass);
33  // console.log(hiddenMobileClass);
34
35  // Set initial visibility
36  // ======================
37  if (navigationList) {
38    navigationList.classList.add(hiddenMobileClass);
39  }
40
41  // Toggle Search
42  // =============
43  function toggleSearch(type) {
44    // Clear current timeout on click to avoid transition problems
45    if (navTimeout) {
46      clearTimeout(navTimeout);
47    }
48    // Open
49    if (type === 'open') {
50      searchWrapper.classList.remove(hiddenMobileClass);
51      search.removeAttribute('tabindex');
52      searchCancel.removeAttribute('tabindex');
53      searchSubmit.removeAttribute('tabindex');
54      // Set timeout so transition can kick in after hidden is removed
55      navTimeout = setTimeout(() => {
56        document.body.classList.add(searchVisibleClass);
57        search.focus();
58      }, 16);
59    }
60    if (type === 'close') {
61      document.body.classList.remove(searchVisibleClass);
62      searchToggle.focus();
63      search.setAttribute('tabindex', '-1');
64      searchCancel.setAttribute('tabindex', '-1');
65      searchSubmit.setAttribute('tabindex', '-1');
66    }
67  }
68
69  // Search event listener
70  // =====================
71  if (search) {
72    search.addEventListener('focus', () => {
73      toggleSearch('open');
74    });
75    // searchCancel.addEventListener('blur', () => {
76    // 	toggleSearch('close');
77    // });
78    // searchToggle.addEventListener('focus', () => {
79    //     if (document.body.classList.contains(searchVisibleClass)) {
80    // 		toggleSearch('close');
81    //     }
82    // });
83  }
84
85  // Toggle Menu
86  // ===========
87  function toggleMenu(type) {
88    // Clear current timeout on click to avoid transition problems
89    if (navTimeout) {
90      clearTimeout(navTimeout);
91    }
92
93    // Open
94    if (type === 'open') {
95      navigationList.classList.remove(hiddenMobileClass);
96      navigationToggle.setAttribute('aria-expanded', 'true');
97      // Set timeout so transition can kick in after hidden is removed
98      navTimeout = setTimeout(() => {
99        document.body.classList.add(navigationVisibleClass);
100      }, 16);
101    }
102
103    // Close
104    if (type === 'close') {
105      document.body.classList.remove(navigationVisibleClass);
106      // Set timeout so transition can kick in before hidden is added
107      navTimeout = setTimeout(() => {
108        navigationList.classList.add(hiddenMobileClass);
109        navigationToggle.setAttribute('aria-expanded', 'false');
110      }, 200);
111    }
112  }
113
114  // Search open
115  // ===========
116  // (button doesn't need a close since it's hidden and focus is being set to input)
117  if (search) {
118    // searchToggle.addEventListener('click', () => {
119    //     toggleSearch('open');
120    // });
121  }
122
123  // Toggle navigation
124  // =================
125  if (navigationToggle) {
126    navigationToggle.addEventListener('click', () => {
127      if (navigationList.classList.contains(hiddenMobileClass)) {
128        toggleMenu('open');
129      } else {
130        toggleMenu('close');
131      }
132    });
133  }
134
135  // Erase / close search
136  // ====================
137  if (searchCancel) {
138    searchCancel.addEventListener('click', () => {
139      if (search.value === '') {
140        toggleSearch('close');
141      } else {
142        search.value = '';
143        search.focus();
144      }
145    });
146  }
147
148  // Set focus on submit when submit is empty
149  if (searchSubmit) {
150    searchSubmit.addEventListener('click', ev => {
151      if (search.value === '') {
152        ev.preventDefault();
153        search.focus();
154      }
155    });
156  }
157
158  // Close search and navigation on click outside
159  // ============================================
160  document.addEventListener('click', ev => {
161    if (!ev.target.closest(searchWrapperClass) && document.body.classList.contains(searchVisibleClass)) {
162      toggleSearch('close');
163    }
164    if (!ev.target.closest(headerNavigationClass) && document.body.classList.contains(navigationVisibleClass)) {
165      toggleMenu('close');
166    }
167  });
168
169  // Close search and navigation on esc key
170  // ======================================
171  document.addEventListener('keydown', ev => {
172    if (ev.key === 'Escape') {
173      if (document.body.classList.contains(searchVisibleClass)) {
174        toggleSearch('close');
175      }
176      if (document.body.classList.contains(navigationVisibleClass)) {
177        toggleMenu('close');
178      }
179    }
180  });
181})();
182
183/* eslint-enable */

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.