PageSourceSearch

https://cvetochka.ru/local/templates/2018/js/main-page-redesign.js

js cvetochka.ru collected 2026-09-26 11:31:24 UTC 11,517 bytes, 364 lines download raw bytes

1(function () {
2    function onReady(callback) {
3        if (document.readyState === 'loading') {
4            document.addEventListener('DOMContentLoaded', callback);
5            return;
6        }
7
8        callback();
9    }
10
11    function initHeroSlider(root) {
12        var slider = root.querySelector('#heroSlider');
13        var track = root.querySelector('#heroTrack');
14
15        if (!slider || !track) {
16            return;
17        }
18
19        var dots = Array.prototype.slice.call(slider.querySelectorAll('.hero-slider__dot'));
20        var prevBtn = slider.querySelector('.hero-slider__arrow--prev');
21        var nextBtn = slider.querySelector('.hero-slider__arrow--next');
22        var total = dots.length;
23        var current = 0;
24        var autoTimer = null;
25        var interval = 6000;
26
27        if (total < 2) {
28            return;
29        }
30
31        function setActiveDot(index) {
32            dots.forEach(function (dot) {
33                dot.classList.remove('active');
34            });
35
36            if (dots[index]) {
37                dots[index].classList.add('active');
38            }
39        }
40
41        function goTo(index) {
42            current = (index + total) % total;
43            track.scrollTo({left: current * track.clientWidth, behavior: 'smooth'});
44            setActiveDot(current);
45        }
46
47        function resetAuto() {
48            clearInterval(autoTimer);
49            autoTimer = setInterval(function () {
50                goTo(current + 1);
51            }, interval);
52        }
53
54        track.addEventListener('scroll', function () {
55            var index = Math.round(track.scrollLeft / track.clientWidth);
56
57            if (index !== current && dots[index]) {
58                current = index;
59                setActiveDot(current);
60            }
61        });
62
63        if (prevBtn) {
64            prevBtn.addEventListener('click', function () {
65                goTo(current - 1);
66                resetAuto();
67            });
68        }
69
70        if (nextBtn) {
71            nextBtn.addEventListener('click', function () {
72                goTo(current + 1);
73                resetAuto();
74            });
75        }
76
77        dots.forEach(function (dot) {
78            dot.addEventListener('click', function () {
79                goTo(Number(dot.dataset.slide || 0));
80                resetAuto();
81            });
82        });
83
84        var startX = 0;
85        var startY = 0;
86        var isDragging = false;
87
88        slider.addEventListener('touchstart', function (event) {
89            startX = event.touches[0].clientX;
90            startY = event.touches[0].clientY;
91            isDragging = true;
92        }, {passive: true});
93
94        slider.addEventListener('mousedown', function (event) {
95            startX = event.clientX;
96            startY = event.clientY;
97            isDragging = true;
98        });
99
100        slider.addEventListener('touchend', function (event) {
101            if (!isDragging) {
102                return;
103            }
104
105            isDragging = false;
106            var dx = event.changedTouches[0].clientX - startX;
107            var dy = event.changedTouches[0].clientY - startY;
108
109            if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 40) {
110                goTo(dx < 0 ? current + 1 : current - 1);
111                resetAuto();
112            }
113        }, {passive: true});
114
115        slider.addEventListener('mouseup', function (event) {
116            if (!isDragging) {
117                return;
118            }
119
120            isDragging = false;
121            var dx = event.clientX - startX;
122
123            if (Math.abs(dx) > 40) {
124                goTo(dx < 0 ? current + 1 : current - 1);
125                resetAuto();
126            }
127        });
128
129        resetAuto();
130    }
131
132    function initProductTabs(root) {
133        var tabs = Array.prototype.slice.call(root.querySelectorAll('[data-product-tab]'));
134        var panels = Array.prototype.slice.call(root.querySelectorAll('[data-product-panel]'));
135        var seeAll = root.querySelector('[data-product-see-all]');
136
137        if (!tabs.length || !panels.length) {
138            return;
139        }
140
141        function activate(code) {
142            tabs.forEach(function (tab) {
143                tab.classList.toggle('active', tab.dataset.productTab === code);
144            });
145
146            panels.forEach(function (panel) {
147                panel.classList.toggle('active', panel.dataset.productPanel === code);
148            });
149
150            var activeTab = tabs.filter(function (tab) {
151                return tab.dataset.productTab === code;
152            })[0];
153
154            if (seeAll && activeTab && activeTab.dataset.productUrl) {
155                seeAll.href = activeTab.dataset.productUrl;
156            }
157            if (seeAll && activeTab && activeTab.dataset.productButton) {
158                seeAll.textContent = activeTab.dataset.productButton;
159            }
160        }
161
162        tabs.forEach(function (tab) {
163            tab.addEventListener('click', function () {
164                activate(tab.dataset.productTab);
165            });
166        });
167    }
168
169    function initCtaSlider(root) {
170        var slider = root.querySelector('.cta-slider');
171        var track = root.querySelector('#ctaTrack');
172
173        if (!slider || !track) {
174            return;
175        }
176
177        var slides = Array.prototype.slice.call(track.querySelectorAll('.cta-banner'));
178        var dots = Array.prototype.slice.call(root.querySelectorAll('.cta-dot'));
179        var total = slides.length;
180        var current = 0;
181        var autoTimer = null;
182        var interval = 6000;
183
184        if (total < 2) {
185            return;
186        }
187
188        function updateDots() {
189            dots.forEach(function (dot) {
190                dot.classList.remove('active', 'contacts-divider__line--pink');
191                dot.classList.add('contacts-divider__line--gray');
192            });
193
194            if (dots[current]) {
195                dots[current].classList.add('active', 'contacts-divider__line--pink');
196                dots[current].classList.remove('contacts-divider__line--gray');
197            }
198        }
199
200        function goTo(index) {
201            current = ((index % total) + total) % total;
202
203            var slideWidth = slides[0].offsetWidth;
204            var gap = parseFloat(window.getComputedStyle(track).gap) || 0;
205            track.style.transform = 'translateX(-' + (current * (slideWidth + gap)) + 'px)';
206            updateDots();
207        }
208
209        function resetAuto() {
210            clearInterval(autoTimer);
211            autoTimer = setInterval(function () {
212                goTo(current + 1);
213            }, interval);
214        }
215
216        dots.forEach(function (dot) {
217            dot.addEventListener('click', function () {
218                goTo(Number(dot.dataset.slide || 0));
219                resetAuto();
220            });
221        });
222
223        var startX = 0;
224        var startY = 0;
225        var isDragging = false;
226
227        slider.addEventListener('touchstart', function (event) {
228            startX = event.touches[0].clientX;
229            startY = event.touches[0].clientY;
230            isDragging = true;
231        }, {passive: true});
232
233        slider.addEventListener('mousedown', function (event) {
234            startX = event.clientX;
235            startY = event.clientY;
236            isDragging = true;
237        });
238
239        slider.addEventListener('touchend', function (event) {
240            if (!isDragging) {
241                return;
242            }
243
244            isDragging = false;
245            var dx = event.changedTouches[0].clientX - startX;
246            var dy = event.changedTouches[0].clientY - startY;
247
248            if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 40) {
249                goTo(dx < 0 ? current + 1 : current - 1);
250                resetAuto();
251            }
252        }, {passive: true});
253
254        slider.addEventListener('mouseup', function (event) {
255            if (!isDragging) {
256                return;
257            }
258
259            isDragging = false;
260            var dx = event.clientX - startX;
261
262            if (Math.abs(dx) > 40) {
263                goTo(dx < 0 ? current + 1 : current - 1);
264                resetAuto();
265            }
266        });
267
268        window.addEventListener('resize', function () {
269            goTo(current);
270        });
271
272        resetAuto();
273    }
274
275    function initCtaActions(root) {
276        root.querySelectorAll('[data-cta-action="chat"]').forEach(function (link) {
277            link.addEventListener('click', function (event) {
278                var opened = false;
279                var widget = document.querySelector('.consultant-icon.ie-fallback');
280
281                event.preventDefault();
282
283                if (widget && typeof widget.click === 'function') {
284                    widget.click();
285                    opened = true;
286                }
287
288                if (!opened && window.jivo_api && typeof window.jivo_api.open === 'function') {
289                    window.jivo_api.open();
290                    opened = true;
291                }
292
293                if (!opened && window.jivo_api && typeof window.jivo_api.openChat === 'function') {
294                    window.jivo_api.openChat();
295                }
296            });
297        });
298    }
299
300    function initHearts(root) {
301        root.querySelectorAll('.main-product-card__heart, .mobile-card__heart').forEach(function (button) {
302            button.addEventListener('click', function (event) {
303                event.preventDefault();
304                event.stopPropagation();
305
306                var productId = button.getAttribute('data-id');
307                if (!productId || button.dataset.loading === 'true') {
308                    return;
309                }
310
311                var targets = Array.prototype.slice.call(document.querySelectorAll('.icon-like[data-id="' + productId + '"]'));
312                var isActive = targets.some(function (target) {
313                    return target.classList.contains('is-active');
314                });
315                var formData = new FormData();
316
317                formData.append('id', productId);
318                formData.append('action', isActive ? 'remove' : 'add');
319                targets.forEach(function (target) {
320                    target.dataset.loading = 'true';
321                });
322
323                fetch('/.ajax/favorites.php', {
324                    method: 'POST',
325                    body: formData,
326                    credentials: 'same-origin'
327                })
328                    .then(function (response) {
329                        return response.json();
330                    })
331                    .then(function (data) {
332                        if (!data || data.STATUS !== 'SUCCESS') {
333                            return;
334                        }
335
336                        targets.forEach(function (target) {
337                            target.classList.toggle('is-active', !isActive);
338                            target.classList.toggle('is-liked', !isActive);
339                        });
340                    })
341                    .catch(function () {})
342                    .finally(function () {
343                        targets.forEach(function (target) {
344                            delete target.dataset.loading;
345                        });
346                    });
347            });
348        });
349    }
350
351    onReady(function () {
352        var root = document.querySelector('.main-page-redesign');
353
354        if (!root) {
355            return;
356        }
357
358        initHeroSlider(root);
359        initProductTabs(root);
360        initCtaSlider(root);
361        initCtaActions(root);
362        initHearts(root);
363    });
364})();

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.