1(function () { 2 "use strict"; 3 4 /** 5 * Apply .scrolled class to the body as the page is scrolled down 6 */ 7 function toggleScrolled() { 8 const selectBody = document.querySelector("body"); 9 const selectHeader = document.querySelector("#header"); 10 if ( 11 !selectHeader.classList.contains("scroll-up-sticky") && 12 !selectHeader.classList.contains("sticky-top") && 13 !selectHeader.classList.contains("fixed-top") 14 ) 15 return; 16 window.scrollY > 100 17 ? selectBody.classList.add("scrolled") 18 : selectBody.classList.remove("scrolled"); 19 } 20 21 document.addEventListener("scroll", toggleScrolled); 22 window.addEventListener("load", toggleScrolled); 23 24 /** 25 * Mobile nav toggle 26 */ 27 const mobileNavToggleBtn = document.querySelector(".mobile-nav-toggle"); 28 29 function mobileNavToogle() { 30 document.querySelector("body").classList.toggle("mobile-nav-active"); 31 mobileNavToggleBtn.classList.toggle("bi-list"); 32 mobileNavToggleBtn.classList.toggle("bi-x"); 33 } 34 mobileNavToggleBtn.addEventListener("click", mobileNavToogle); 35 36 /** 37 * Hide mobile nav on same-page/hash links 38 */ 39 document.querySelectorAll("#navmenu a").forEach((navmenu) => { 40 navmenu.addEventListener("click", () => { 41 if (document.querySelector(".mobile-nav-active")) { 42 mobileNavToogle(); 43 } 44 }); 45 }); 46 47 /** 48 * Toggle mobile nav dropdowns 49 */ 50 document.querySelectorAll(".navmenu .toggle-dropdown").forEach((navmenu) => { 51 navmenu.addEventListener("click", function (e) { 52 e.preventDefault(); 53 this.parentNode.classList.toggle("active"); 54 this.parentNode.nextElementSibling.classList.toggle("dropdown-active"); 55 e.stopImmediatePropagation(); 56 }); 57 }); 58 59 /** 60 * Preloader 61 */ 62 const preloader = document.querySelector("#preloader"); 63 if (preloader) { 64 // Remove preloader after DOM is ready or after 1 second max 65 const removePreloader = () => { 66 preloader.style.opacity = "0"; 67 setTimeout(() => { 68 preloader.remove(); 69 }, 300); 70 }; 71 72 // Remove preloader when DOM is ready 73 if (document.readyState === "complete") { 74 removePreloader(); 75 } else { 76 // Set a maximum timeout of 1 second 77 const maxTimeout = setTimeout(removePreloader, 1000); 78 79 // Or remove when page loads, whichever comes first 80 window.addEventListener("load", () => { 81 clearTimeout(maxTimeout); 82 removePreloader(); 83 }); 84 } 85 } 86 87 /** 88 * Scroll top button 89 */ 90 let scrollTop = document.querySelector(".scroll-top"); 91 92 function toggleScrollTop() { 93 if (scrollTop) { 94 window.scrollY > 100 95 ? scrollTop.classList.add("active") 96 : scrollTop.classList.remove("active"); 97 } 98 } 99 scrollTop.addEventListener("click", (e) => { 100 e.preventDefault(); 101 window.scrollTo({ 102 top: 0, 103 behavior: "smooth", 104 }); 105 }); 106 107 window.addEventListener("load", toggleScrollTop); 108 document.addEventListener("scroll", toggleScrollTop); 109 110 /** 111 * Animation on scroll function and init 112 */ 113 function aosInit() { 114 AOS.init({ 115 duration: 600, 116 easing: "ease-in-out", 117 once: true, 118 mirror: false, 119 }); 120 } 121 window.addEventListener("load", aosInit); 122 123 /** 124 * Initiate glightbox 125 */ 126 const glightbox = GLightbox({ 127 selector: ".glightbox", 128 }); 129 130 /** 131 * Initiate Pure Counter 132 */ 133 new PureCounter(); 134 135 /** 136 * Init swiper sliders 137 */ 138 function initSwiper() { 139 document.querySelectorAll(".init-swiper").forEach(function (swiperElement) { 140 let config = JSON.parse( 141 swiperElement.querySelector(".swiper-config").innerHTML.trim() 142 ); 143 144 if (swiperElement.classList.contains("swiper-tab")) { 145 initSwiperWithCustomPagination(swiperElement, config); 146 } else { 147 new Swiper(swiperElement, config); 148 } 149 }); 150 } 151 152 window.addEventListener("load", initSwiper); 153 154 /** 155 * Init isotope layout and filters 156 */ 157 document.querySelectorAll(".isotope-layout").forEach(function (isotopeItem) { 158 let layout = isotopeItem.getAttribute("data-layout") ?? "masonry"; 159 let filter = isotopeItem.getAttribute("data-default-filter") ?? "*"; 160 let sort = isotopeItem.getAttribute("data-sort") ?? "original-order"; 161 162 let initIsotope; 163 imagesLoaded(isotopeItem.querySelector(".isotope-container"), function () { 164 initIsotope = new Isotope( 165 isotopeItem.querySelector(".isotope-container"), 166 { 167 itemSelector: ".isotope-item", 168 layoutMode: layout, 169 filter: filter, 170 sortBy: sort,
171 } 172 ); 173 }); 174 175 isotopeItem 176 .querySelectorAll(".isotope-filters li") 177 .forEach(function (filters) { 178 filters.addEventListener( 179 "click", 180 function () { 181 isotopeItem 182 .querySelector(".isotope-filters .filter-active") 183 .classList.remove("filter-active"); 184 this.classList.add("filter-active"); 185 initIsotope.arrange({ 186 filter: this.getAttribute("data-filter"), 187 }); 188 if (typeof aosInit === "function") { 189 aosInit(); 190 } 191 }, 192 false 193 ); 194 }); 195 }); 196 197 /** 198 * Correct scrolling position upon page load for URLs containing hash links. 199 */ 200 window.addEventListener("load", function (e) { 201 if (window.location.hash) { 202 if (document.querySelector(window.location.hash)) { 203 setTimeout(() => { 204 let section = document.querySelector(window.location.hash); 205 let scrollMarginTop = getComputedStyle(section).scrollMarginTop; 206 window.scrollTo({ 207 top: section.offsetTop - parseInt(scrollMarginTop), 208 behavior: "smooth", 209 }); 210 }, 100); 211 } 212 } 213 }); 214 215 /** 216 * Navmenu Scrollspy 217 */ 218 let navmenulinks = document.querySelectorAll(".navmenu a"); 219 220 function navmenuScrollspy() { 221 navmenulinks.forEach((navmenulink) => { 222 if (!navmenulink.hash) return; 223 let section = document.querySelector(navmenulink.hash); 224 if (!section) return; 225 let position = window.scrollY + 200; 226 if ( 227 position >= section.offsetTop && 228 position <= section.offsetTop + section.offsetHeight 229 ) { 230 document 231 .querySelectorAll(".navmenu a.active") 232 .forEach((link) => link.classList.remove("active")); 233 navmenulink.classList.add("active"); 234 } else { 235 navmenulink.classList.remove("active"); 236 } 237 }); 238 } 239 window.addEventListener("load", navmenuScrollspy); 240 document.addEventListener("scroll", navmenuScrollspy); 241})(); 242 243/** 244 * Frequently Asked Questions Toggle 245 */ 246document 247 .querySelectorAll(".faq-item h3, .faq-item .faq-toggle") 248 .forEach((faqItem) => { 249 faqItem.addEventListener("click", () => { 250 faqItem.parentNode.classList.toggle("faq-active"); 251 }); 252 });
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.