PageSourceSearch

https://vrein.ai/assets/js/main.js

js vrein.ai collected 2026-10-05 14:38:06 UTC 7,146 bytes, 252 lines download raw bytes

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.