PageSourceSearch

https://gamblingnorge.com/js/main.js

js gamblingnorge.com collected 2026-10-04 16:07:39 UTC 3,933 bytes, 121 lines download raw bytes

1// HTML is static in every page. JavaScript only adds small interactions.
2
3// ---------- FAQ accordion ----------
4function initFaq() {
5  const list = document.getElementById("faqList");
6  if (!list) return;
7  list.querySelectorAll(".faq-item").forEach((item) => {
8    const btn = item.querySelector(".faq-q");
9    const ans = item.querySelector(".faq-a");
10    btn.addEventListener("click", () => {
11      const isOpen = item.classList.contains("open");
12      list.querySelectorAll(".faq-item.open").forEach((openItem) => {
13        if (openItem !== item) {
14          openItem.classList.remove("open");
15          openItem.querySelector(".faq-a").style.maxHeight = null;
16          openItem.querySelector(".faq-q").setAttribute("aria-expanded", "false");
17        }
18      });
19      item.classList.toggle("open", !isOpen);
20      btn.setAttribute("aria-expanded", String(!isOpen));
21      ans.style.maxHeight = isOpen ? null : `${ans.scrollHeight}px`;
22    });
23  });
24}
25
26// ---------- Mobile menu ----------
27function initMenu() {
28  const toggle = document.getElementById("navToggle");
29  const links = document.getElementById("navLinks");
30  if (!toggle || !links) return;
31  toggle.addEventListener("click", () => {
32    const open = links.classList.toggle("open");
33    toggle.setAttribute("aria-expanded", String(open));
34  });
35  links.querySelectorAll("a").forEach((link) =>
36    link.addEventListener("click", () => {
37      links.classList.remove("open");
38      links.querySelectorAll(".nav-dropdown.open").forEach((dropdown) => {
39        dropdown.classList.remove("open");
40        dropdown.querySelector(".nav-dropdown-toggle")?.setAttribute("aria-expanded", "false");
41      });
42      toggle.setAttribute("aria-expanded", "false");
43    })
44  );
45}
46
47// ---------- Casino dropdown ----------
48function initCasinoDropdown() {
49  const dropdowns = document.querySelectorAll(".nav-dropdown");
50  if (!dropdowns.length) return;
51
52  const closeDropdowns = (current = null) => {
53    dropdowns.forEach((dropdown) => {
54      if (dropdown === current) return;
55      dropdown.classList.remove("open");
56      dropdown.querySelector(".nav-dropdown-toggle")?.setAttribute("aria-expanded", "false");
57    });
58  };
59
60  dropdowns.forEach((dropdown) => {
61    const button = dropdown.querySelector(".nav-dropdown-toggle");
62    if (!button) return;
63
64    button.addEventListener("click", (event) => {
65      event.stopPropagation();
66      const isOpen = dropdown.classList.contains("open");
67      closeDropdowns(dropdown);
68      dropdown.classList.toggle("open", !isOpen);
69      button.setAttribute("aria-expanded", String(!isOpen));
70    });
71  });
72
73  document.addEventListener("click", (event) => {
74    if (event.target.closest(".nav-dropdown")) return;
75    closeDropdowns();
76  });
77
78  document.addEventListener("keydown", (event) => {
79    if (event.key !== "Escape") return;
80    closeDropdowns();
81  });
82}
83
84// ---------- Scroll reveal ----------
85function initReveal() {
86  const elements = document.querySelectorAll(".reveal");
87  if (!("IntersectionObserver" in window)) {
88    elements.forEach((element) => element.classList.add("visible"));
89    return;
90  }
91  const observer = new IntersectionObserver(
92    (entries) => {
93      entries.forEach((entry) => {
94        if (entry.isIntersecting) {
95          entry.target.classList.add("visible");
96          observer.unobserve(entry.target);
97        }
98      });
99    },
100    { threshold: 0.12 }
101  );
102  elements.forEach((element) => observer.observe(element));
103}
104
105// ---------- Affiliate click tracking ----------
106function initAffiliateTracking() {
107  document.addEventListener("click", (event) => {
108    const link = event.target.closest("[data-affiliate]");
109    if (!link) return;
110    const id = link.getAttribute("data-affiliate");
111    console.log("[affiliate] click:", id);
112  });
113}
114
115document.addEventListener("DOMContentLoaded", () => {
116  initFaq();
117  initMenu();
118  initCasinoDropdown();
119  initReveal();
120  initAffiliateTracking();
121});

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.