PageSourceSearch

https://www.sb.by/local/templates/media/components/header-header-menu.js?17799676036350

js sb.by collected 2026-09-24 08:46:25 UTC 6,350 bytes, 187 lines download raw bytes

1class SlamMenu {
2    constructor({ navList, clearOnMouseleave = false }) {
3        this.wrapper = navList
4        this.clearOnMouseleave = clearOnMouseleave
5        this.pageX = 0
6        this.currentItem = null
7        this.listen()
8    }
9
10    listen() {
11
12        if(  window.slam.app.isMobile()){
13            return
14        }else{
15            this.wrapper.querySelector('.slam-menu__nav-item').classList.add('active')
16        }
17      
18
19        this.wrapper.addEventListener(
20            'mousemove',
21            (ev) => {
22                const item = ev.target.closest('li')
23                if (item && item.parentNode == ev.currentTarget) {
24                    if (this.pageX == 0) {
25                        // this.currentItem = item;
26                        this.pageX = ev.pageX
27                    }
28                    setTimeout(() => {
29                        this.pageX = ev.pageX
30                    }, 100)
31                    if (ev.pageX > this.pageX + 10) {
32                        return
33                    } else {
34                        if (this.currentItem == item) return
35                        this.removeActivity()
36                        item.classList.add('active')
37                        this.currentItem = item
38                    }
39                }
40            },
41            { capture: true }
42        )
43
44        if (document.querySelector('body').classList.contains('touchable-device')) {
45            this.wrapper.addEventListener(
46                'touchend',
47                (ev) => {
48                    const item = ev.target.closest('li.has-nav')
49                    if (item && item.parentNode == ev.currentTarget) {
50                        if (item.classList.contains('touch-ev')) {
51                            return
52                        }
53                        this.removeActivity()
54                        item.classList.add('active')
55                        item.classList.add('touch-ev')
56                        ev.stopPropagation()
57                        if (ev.cancelable) ev.preventDefault()
58                    }
59                },
60                { passive: false }
61            )
62        }
63
64        if (this.clearOnMouseleave) {
65            this.wrapper.addEventListener('mouseleave', () => {
66                this.wrapper.querySelectorAll('& > li').forEach((x) => {
67                    x.classList.remove('active')
68                })
69                this.pageX = 0
70                this.currentItem = null
71            })
72        }
73    }
74
75    removeActivity() {
76        this.wrapper.querySelectorAll('& > li').forEach((x) => {
77            x.classList.remove('active')
78            x.classList.remove('touch-ev')
79        })
80    }
81}
82
83function HeaderMenu() {
84    const app = {
85        active: false,
86        init() {
87            this.menu = document.querySelector('.js-slam-menu')
88            this.button = document.querySelector('.js-main-menu-button')
89            this.sbtn = document.querySelector('.js-social-btn')
90            if (!this.button) return false
91            this.button.addEventListener('click', this.toggle.bind(this))
92            if (this.sbtn) {
93              this.sbtn.addEventListener('click', this.sbtn_toggle.bind(this))
94            }
95
96            new SlamMenu({
97                navList: document.querySelector('.js-slam-menu .js-navlist'),
98            })
99            this.initNavItemToggles()
100            window.slam.app.clickOutside([this.menu, this.button, this.sbtn], this.close.bind(this))
101            //window.slam.app.clickOutside([this.sbtn], this.sbtn_close.bind(this))
102        },
103
104        initNavItemToggles() {
105            if (!this.menu) return
106            const items = this.menu.querySelectorAll('.slam-menu__nav-item')
107            const toggles = this.menu.querySelectorAll('.js-nav-item-toggle')
108
109            toggles.forEach((toggle) => {
110                toggle.addEventListener('click', (ev) => {
111                    ev.preventDefault()
112                    const item = ev.currentTarget.closest('.slam-menu__nav-item')
113                    if (!item) return
114
115                    const isActive = item.classList.contains('active')
116
117                    items.forEach((li) => {
118                        li.classList.remove('active')
119                    })
120
121                    if (!isActive) {
122                        item.classList.add('active')
123                    }
124                })
125            })
126        },
127        sbtn_toggle() {
128          let active = this.sbtn.classList.contains('active')
129          
130          if (active) {
131            this.sbtn_close()
132          } else {
133            this.sbtn_open()
134          }
135        },
136        sbtn_open() {
137            this.close()
138            this.menu.classList.add('active')
139            this.sbtn.classList.add('active')
140            this.menu.classList.add('active-social')
141            window.slam.app.lockBody()
142        },
143        sbtn_close() {
144            this.sbtn.classList.remove('active')
145            this.menu.classList.remove('active-social')
146            this.menu.classList.remove('active')
147            window.slam.app.unlockBody(this.sbtn, 'i-close')
148        },
149        open() {
150            this.sbtn_close()
151            this.active = true
152            this.button.classList.add('active')
153            this.menu.classList.add('active')
154            window.slam.app.setIcon(this.button, 'i-close')
155            window.slam.app.lockBody()
156            // window.slam.app.addBackdrop()
157        },
158        close() {
159            if (this.active) {
160                this.active = false
161                this.button.classList.remove('active')
162                this.menu.classList.remove('active')
163                window.slam.app.setIcon(this.button, 'i-burger')
164                window.slam.app.unlockBody(this.button, 'i-close')
165                // window.slam.app.removeBackdrop()
166                this.sbtn.classList.remove('active')
167                this.menu.classList.remove('active-social')
168
169            }
170        },
171        toggle() {
172            this.active ? this.close() : this.open()
173        },
174    }
175
176    app.init()
177
178    if (typeof window !== 'undefined') {
179        window.slam = window.slam || {}
180        window.slam.headerMenu = app
181    }
182}
183
184if (typeof window !== 'undefined') {
185    window.addEventListener('ReactContentLoaded', HeaderMenu)
186    document.addEventListener('DOMContentLoaded', HeaderMenu)
187}

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.