PageSourceSearch

https://www.sb.by/local/templates/media/components/db.by/main.news.list/feed/script.js?17866059267410

js sb.by collected 2026-09-24 08:46:30 UTC 7,410 bytes, 238 lines download raw bytes

1function initNewsFeedInstance(feed, scrollContainer) {
2
3    if (!feed) return;
4
5    const list = feed.querySelector('.news-feed__list')
6    if (!list) return;
7
8    const app = {
9        init() {
10
11            this.page = 1
12            this.feed = feed
13            this.list = list
14
15            this.scrollContainer = scrollContainer || window
16
17            this.isLoading = false
18            this.hasMore = true
19            this.page = 2
20            this.maxPages = 20
21            this.ajaxUrl = window.feed_ajax_path + '/include_component.php'
22            this.isMobile = window.matchMedia('(max-width: 767px)').matches
23
24            this.bindLoadMoreButton()
25
26            if (!this.isMobile) {
27                this.createSentinel()
28                this.initObserver()
29            }
30            this.handleResize = () => {
31                const isMobileNow = window.matchMedia('(max-width: 767px)').matches
32
33                if (isMobileNow !== this.isMobile) {
34                    this.isMobile = isMobileNow
35
36                    if (this.isMobile) {
37                        // выключаем infinite scroll
38                        if (this.observer && this.sentinel) {
39                            this.observer.unobserve(this.sentinel)
40                            this.observer.disconnect()
41                        }
42                    } else {
43                        // включаем обратно
44                        this.createSentinel()
45                        this.initObserver()
46                    }
47                }
48            }
49
50            window.addEventListener('resize', this.handleResize)
51        },
52
53        createSentinel() {
54            const existing = this.list.querySelector('.news-feed__sentinel')
55            if (existing) {
56                this.sentinel = existing
57                return
58            }
59
60            const sentinel = document.createElement('div')
61            sentinel.className = 'news-feed__sentinel'
62            this.list.appendChild(sentinel)
63            this.sentinel = sentinel
64        },
65
66        initObserver() {
67
68            const root =
69                this.scrollContainer && this.scrollContainer !== window
70                    ? this.scrollContainer
71                    : null
72
73            console.log('root',root)
74
75            this.observer = new IntersectionObserver(
76                (entries) => {
77                    entries.forEach((entry) => {
78                        if (entry.isIntersecting) {
79                            this.loadMore()
80                        }
81                    })
82                },
83                {
84                    root,
85                    rootMargin: '200px',
86                    threshold: 0,
87                }
88            )
89
90            this.observer.observe(this.sentinel)
91        },
92
93        bindLoadMoreButton() {
94            const btn = this.feed.querySelector('.news-feed__more a')
95            if (!btn) return
96
97            this.loadMoreBtn = btn
98
99            this.loadMoreHandler = (e) => {
100                e.preventDefault()
101                this.loadMore()
102            }
103
104            btn.addEventListener('click', this.loadMoreHandler)
105        },
106        executeScripts(item) {
107          // Находим все скрипты внутри добавленной карточки
108          const scripts = item.querySelectorAll('script');
109          
110          scripts.forEach((oldScript) => {
111            const newScript = document.createElement('script');
112            
113            // Копируем содержимое скрипта
114            if (oldScript.innerHTML) {
115              newScript.innerHTML = oldScript.innerHTML;
116            }
117            
118            // Копируем атрибуты (src, async и т.д.), если они есть
119            Array.from(oldScript.attributes).forEach((attr) => {
120              newScript.setAttribute(attr.name, attr.value);
121            });
122            
123            // Заменяем старый скрипт на новый, чтобы браузер его выполнил
124            oldScript.parentNode.replaceChild(newScript, oldScript);
125          });
126        },
127
128        async loadMore() {
129            if (this.isLoading || !this.hasMore) {
130                return
131            }
132
133            if (this.page > this.maxPages) {
134                this.hasMore = false
135                this.destroy()
136                return
137            }
138
139            this.isLoading = true
140            this.feed.classList.add('news-feed--loading')
141
142            try {
143                const url = `${this.ajaxUrl}?PAGEN=${this.page}`
144
145                const response = await fetch(url, {
146                    headers: {
147                        'X-Requested-With': 'XMLHttpRequest',
148                    },
149                    cache: 'no-cache',
150                })
151
152                if (!response.ok) {
153                    throw new Error('Failed to load news feed')
154                }
155
156                const html = await response.text()
157
158                const wrapper = document.createElement('div')
159                wrapper.innerHTML = html
160
161                const ajaxList = wrapper.querySelector('.news-feed__list')
162                const source =
163                    ajaxList && ajaxList.children.length
164                        ? ajaxList
165                        : wrapper
166
167                const items = Array.from(
168                    source.querySelectorAll('.feed-card')
169                )
170
171                items.forEach((item) => {
172                    this.list.insertBefore(item, this.sentinel);
173                    this.executeScripts(item);
174                })
175
176                this.page++
177            } catch (e) {
178                console.error(e)
179                this.hasMore = false
180                this.destroy()
181            } finally {
182                this.isLoading = false
183                this.feed.classList.remove('news-feed--loading')
184            }
185        },
186
187        destroy() {
188            if (this.observer && this.sentinel) {
189                this.observer.unobserve(this.sentinel)
190                this.observer.disconnect()
191            }
192
193            if (this.scrollHandler && this.scrollTarget) {
194                this.scrollTarget.removeEventListener('scroll', this.scrollHandler)
195            }
196
197            if (this.sentinel && this.sentinel.parentNode) {
198                this.sentinel.parentNode.removeChild(this.sentinel)
199            }
200
201            if (this.loadMoreBtn && this.loadMoreHandler) {
202                this.loadMoreBtn.removeEventListener('click', this.loadMoreHandler)
203            }
204
205            if (this.handleResize) {
206                window.removeEventListener('resize', this.handleResize)
207            }
208        },
209    }
210
211    app.init()
212}
213
214function NewsFeedScript() {
215    const feeds = document.querySelectorAll('.js-news-feed:not(.no-auto-load)')
216    if (!feeds.length) return
217
218    feeds.forEach((feed) =>
219        initNewsFeedInstance(feed)
220    )
221}
222
223if (typeof window !== 'undefined') {
224    if (!window.slam) {
225        window.slam = {}
226    }
227
228    window.slam.NewsFeedScriptInit = function (feed) {
229        const container = document.querySelector(
230            '.js-news-feed-target .news-feed__list:not(.no-auto-load)'
231        )
232
233        initNewsFeedInstance(feed, container)
234    }
235    window.addEventListener('ReactContentLoaded', NewsFeedScript)
236    document.addEventListener('DOMContentLoaded', NewsFeedScript)
237}
238

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.