PageSourceSearch

https://pioneerdjschool.ru/header-navigation.js?v=20260911-header-layout1

js pioneerdjschool.ru collected 2026-10-06 06:51:17 UTC 3,412 bytes, 85 lines download raw bytes

1(() => {
2  let activeMenu = null
3
4  document.querySelectorAll("[data-services-nav], [data-mobile-catalog]").forEach(menu => {
5    const trigger = menu.querySelector(".nav-services-trigger")
6    const panel = menu.querySelector("[data-services-panel]")
7    const link = menu.querySelector("[data-catalog-link]")
8    const mobile = menu.hasAttribute("data-mobile-catalog")
9    if (!trigger || !panel) return
10    let closeTimer
11    let imagesPrepared = false
12
13    const controller = { menu, trigger, close: () => setOpen(false) }
14    const setOpen = open => {
15      window.clearTimeout(closeTimer)
16      if (open) {
17        if (activeMenu !== controller) activeMenu?.close()
18        activeMenu = controller
19        if (!imagesPrepared) {
20          panel.querySelectorAll("[data-service-image]").forEach(item => {
21            item.style.setProperty("--service-image", `url("${item.dataset.serviceImage}")`)
22            if (item.dataset.serviceFit) item.style.setProperty("--service-fit", item.dataset.serviceFit)
23          })
24          imagesPrepared = true
25        }
26      } else if (activeMenu === controller) {
27        activeMenu = null
28      }
29      menu.classList.toggle("is-open", open)
30      trigger.setAttribute("aria-expanded", String(open))
31      panel.setAttribute("aria-hidden", String(!open))
32      panel.inert = !open
33      if (mobile) panel.hidden = !open
34    }
35
36    const openOnHover = event => {
37      if (event.pointerType === "mouse" || event.pointerType === "pen") setOpen(true)
38    }
39    const scheduleClose = () => {
40      window.clearTimeout(closeTimer)
41      closeTimer = window.setTimeout(() => {
42        if (!menu.matches(":hover") && !menu.contains(document.activeElement)) setOpen(false)
43      }, 220)
44    }
45
46    trigger.addEventListener("click", () => setOpen(!menu.classList.contains("is-open")))
47    if (!mobile) {
48      menu.addEventListener("pointerenter", openOnHover)
49      panel.addEventListener("pointerenter", openOnHover)
50      menu.addEventListener("pointerleave", scheduleClose)
51      panel.addEventListener("pointerleave", scheduleClose)
52    }
53    menu.addEventListener("focusout", event => {
54      if (!menu.contains(event.relatedTarget)) setOpen(false)
55    })
56    menu.addEventListener("keydown", event => {
57      if (event.key !== "ArrowDown" || (event.target !== trigger && event.target !== link)) return
58      event.preventDefault()
59      setOpen(true)
60      panel.querySelector("a[href], button:not([disabled])")?.focus()
61    })
62    setOpen(false)
63  })
64
65  document.addEventListener("click", event => {
66    if (activeMenu && !activeMenu.menu.contains(event.target)) activeMenu.close()
67  })
68  document.addEventListener("keydown", event => {
69    if (event.key !== "Escape" || !activeMenu) return
70    const { menu, trigger, close } = activeMenu
71    const restoreFocus = menu.contains(document.activeElement)
72    event.preventDefault()
73    close()
74    if (restoreFocus) trigger.focus()
75  })
76  window.matchMedia("(min-width: 1201px)").addEventListener("change", ({ matches }) => {
77    activeMenu?.close()
78    if (!matches) return
79    document.body.classList.remove("menu-open")
80    document.querySelector(".menu-button")?.setAttribute("aria-expanded", "false")
81    const mobileMenu = document.querySelector(".mobile-menu")
82    mobileMenu?.setAttribute("aria-hidden", "true")
83    mobileMenu?.querySelectorAll("details").forEach(details => { details.open = false })
84  })
85})()

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.