PageSourceSearch

https://alpinabook.ru/local/templates/.default/components/bitrix/advertising.banner/slick_slider/script.js

js alpinabook.ru collected 2026-09-24 08:56:29 UTC 8,280 bytes, 220 lines download raw bytes

1document.addEventListener('DOMContentLoaded', function() {
2
3    // фронтовый компонент public/local/markup/src/component/mainPage-carousel-v2/
4    
5    const HeroSlider = {
6        init() {
7            initSlider();
8        },
9
10        enableAutoplay() {
11            enableAutoplay();
12        }
13    };
14
15    const $root = $('.js-carousel-main')
16    const $btnMob = $root.find('.js-carousel-main__bottom-link')
17    const $slickSlider = $root.find('.js-carousel-main__slick')
18    const $btnPrev = $root.find('[data-role="prev"]');
19    const $btnNext = $root.find('[data-role="next"]');
20    const $slides = $root.find('.js-carousel-main__slide');
21    const responsiveSettings = { fade: true, cssEase: 'ease-out' };
22    let sliderInitialized = false;
23    let autoplayEnabled = false;
24    let autoplayTimeout = null;
25
26    let isMobile = window.innerWidth < globObj.breakpoints.lg;
27
28    window.addEventListener('resize', () => {
29        isMobile = window.innerWidth < globObj.breakpoints.lg;
30    });
31
32    function preloadPicture($img) {
33        const img = $img[0];
34        if (!img || img.dataset.preloaded) return;
35
36        const picture = img.closest('picture');
37        if (!picture) return;
38
39        picture.querySelectorAll('source').forEach((source) => {
40            if (source.dataset.srcset) {
41                source.srcset = source.dataset.srcset;
42            }
43        });
44
45        if (img.dataset.src) img.src = img.dataset.src;
46        if (img.dataset.srcset) img.srcset = img.dataset.srcset;
47
48        img.dataset.preloaded = 'true';
49    }
50
51    function initSlider() {
52        
53        if (sliderInitialized) return;
54
55        $slickSlider.on({
56            init: (event, slick) => {
57                if (slick.initializedOnce) return;
58                slick.initializedOnce = true;
59                
60                handleButtonMobile(slick.currentSlide)
61                preloadPicture($root.find(`.js-carousel-main__slide[data-slide-index="${slick.currentSlide+1}"]`).find('.js-carousel-main__img'))
62                
63                const supportsTouch = $('html').hasClass('touch');
64                const useDoubleTapOnTouch = false; // использовать двойной тап на мобиле для перехода по ссылке
65
66                $slides.each(function(index, element) {
67                    const slideInner = element.querySelector('.carousel-main__slide');
68                    if (supportsTouch && useDoubleTapOnTouch) {
69                        if (element.dataset.btnLink && slideInner) {
70                            let lastTapTime = 0;
71                            slideInner.addEventListener('touchend', function(event) {
72                                const currentTime = new Date().getTime();
73                                const tapTime = currentTime - lastTapTime;
74                                if (tapTime < 500) { // двойное касание было обнаружено
75                                    // window.open(element.dataset.btnLink, '_blank');
76                                    if ('bannerStatisticId' in element.dataset)
77                                        statClick(element.dataset.bannerStatisticId);
78                                    document.location.href = element.dataset.btnLink;
79                                }
80                                lastTapTime = currentTime;
81                            });
82                        }
83                    } else {
84                        if (element.dataset.btnLink && slideInner) {
85                            const a = document.createElement('a');
86                            a.href = element.dataset.btnLink;
87                            a.className = 'carousel-main__slide-link';
88                            a.onclick = function () {
89                                'bannerStatisticId' in element.dataset && statClick(element.dataset.bannerStatisticId);
90                            };
91                            a.onauxclick = function () {
92                                'bannerStatisticId' in element.dataset && statClick(element.dataset.bannerStatisticId);
93                            };
94                            // Такое требование для десктопа – открывать в новой вкладке
95                            // Проверяем по тач-дисплею – хоть и не совсем корректно, но в данном случае допустимо
96                            if (!supportsTouch) {
97                                a.target = '_blank';
98                            }
99                            slideInner.appendChild(a);
100                        }
101                    }
102                })
103            },
104            beforeChange: (event, slick, currentSlide, nextSlide) => {
105                handleButtonMobile(nextSlide)
106
107                const max = slick.$slides.length;
108                preloadPicture(slick.$slides.eq(nextSlide).find('.js-carousel-main__img'));
109                if (nextSlide + 1 < max) {
110                    preloadPicture(slick.$slides.eq(nextSlide+1).find('.js-carousel-main__img'));
111                }
112            },
113        })
114        
115        let settingsResponsive = [
116            {
117                breakpoint: globObj.breakpoints.md,
118                settings: responsiveSettings,
119            },
120        ]
121        
122        if (!isMobile) {
123            settingsResponsive.push({
124                breakpoint: globObj.breakpoints.lg,
125                settings: Object.assign({
126                    arrows: true,
127                    prevArrow: $btnPrev,
128                    nextArrow: $btnNext,
129                }, responsiveSettings)
130            });
131        }
132        
133        $slickSlider
134            .slick({
135                mobileFirst: true,
136                slidesToShow: 1,
137                slidesToScroll: 1,
138                arrows: false,
139                dots: true,
140                appendDots: '.js-carousel-main__dots',
141                dotsClass: 'carousel-main__dots',
142                touchThreshold: 10,
143                infinite: true,
144                responsive: settingsResponsive,
145            });
146
147        function handleButtonMobile (slideIndex) {
148            const $slide = $slickSlider.find('.js-carousel-main__slide').eq(slideIndex);
149            const btnText = $slide.attr('data-btn-text');
150            if (btnText) {
151                $btnMob
152                    .attr('href', $slide.attr('data-btn-link'))
153                    .html ($slide.attr('data-btn-text'))
154                    .css ({
155                        backgroundColor: $slide.attr ('data-mob-btn-bg'),
156                        color: $slide.attr ('data-mob-btn-color'),
157                        opacity: 1
158                    })
159            } else {
160                $btnMob
161                    .attr('href', 'javascript:;')
162                    .html('')
163                    .css({
164                        backgroundColor: 'none',
165                        color: 'black',
166                        opacity: 0
167                    });
168            }
169        }
170
171        sliderInitialized = true;
172    }
173    
174    function enableAutoplay() {
175
176        if (!sliderInitialized) return;
177        if (autoplayEnabled) return;
178        
179        if (!isMobile) {
180            let autoplayInitialized = false;
181
182            // if (autoplayTimeout) clearTimeout(autoplayTimeout);
183            // autoplayTimeout = setTimeout(enable, 10000);
184
185            enable();
186
187            function enable() {
188                if (autoplayInitialized) return;
189                autoplayInitialized = true;
190
191                clearTimeout(autoplayTimeout);
192
193                $slickSlider.slick('slickSetOption', 'autoplay', true, false);
194                $slickSlider.slick('slickPlay');
195
196                autoplayEnabled = true;
197            }
198        }
199    }
200
201    PPO.register({
202        name: 'hero:interactive',
203        condition(state) {
204            return state.lcp && state.idle;
205        },
206        action() {
207            HeroSlider.init();
208        }
209    });
210
211    PPO.register({
212        name: 'hero:autoplay',
213        condition: state => state.interaction,
214        action() {
215            if (!autoplayEnabled) {
216                HeroSlider.enableAutoplay();
217            }
218        }
219    });
220});

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.