PageSourceSearch

https://travel-agent.ru/js/script.add.js?20260806173600

js travel-agent.ru collected 2026-10-01 23:46:50 UTC 10,567 bytes, 282 lines download raw bytes

1(function() {
2    document.addEventListener("click", handler);
3    function handler(e) {
4        const t = e.target;
5        const tClass = "f-info__close-btn";
6        if (t.closest("." + tClass) === null) return false;
7        t.closest(".f-info").classList.add('hidden');
8
9        $.ajax({
10            method: 'post',
11            url: '/ajax/cookie/strip/',
12            data: {lifetime: $('.' + tClass).data('lifetime')},
13            dataType: 'json'
14        });
15    }
16})();
17
18
19document.addEventListener('DOMContentLoaded', function() {
20    const sliderInner = document.querySelector('.section-carousel__slider-inner');
21    const prevButton = document.querySelector('.prev');
22    const nextButton = document.querySelector('.next');
23    const numberDisplay = document.querySelector('.number');
24    const slides = document.querySelectorAll('.slider-item');
25
26    if (!slides.length) return;
27
28    const slideWidth = slides[0].offsetWidth;
29    const slideMargin = parseInt(window.getComputedStyle(slides[0]).marginRight);
30    const totalSlideWidth = slideWidth + slideMargin;
31    const visibleSlides = 2; // Количество видимых слайдов в конце
32
33    let currentSlide = 0;
34    let isDragging = false;
35    let startPosX = 0;
36    let currentTranslate = 0;
37    let prevTranslate = 0;
38    let animationID = 0;
39    let wasDragging = false;
40    let targetDown;
41    let targetUp;
42
43    // Функция для обновления слайдера
44    function updateSlider() {
45        // Максимальный индекс слайда теперь учитывает 2 видимых слайда
46        const maxSlide = slides.length - visibleSlides;
47        currentSlide = Math.max(0, Math.min(currentSlide, maxSlide));
48
49        // Смещение рассчитываем так, чтобы последние 2 слайда были видны
50        const offset = -currentSlide * totalSlideWidth;
51        sliderInner.style.transform = `translate3d(${offset}px, 0px, 0px)`;
52        sliderInner.style.transition = 'transform 0.5s ease';
53
54        numberDisplay.textContent = `${currentSlide + 1}/${slides.length}`;
55
56        prevButton.disabled = currentSlide === 0;
57        nextButton.disabled = currentSlide === maxSlide;
58    }
59
60    // Обработка клика на кнопки
61    prevButton.addEventListener('click', function() {
62        if (currentSlide > 0) {
63            currentSlide--;
64            updateSlider();
65        }
66    });
67
68    nextButton.addEventListener('click', function() {
69        if (currentSlide < slides.length - visibleSlides) {
70            currentSlide++;
71            updateSlider();
72        }
73    });
74
75    // Функции для перетаскивания мышью
76    function getPositionX(event) {
77        return event.type.includes('mouse') ? event.pageX : event.touches[0].clientX;
78    }
79
80    function startDrag(event) {
81        if (window.innerWidth > 1100) {
82            isDragging = true;
83            targetDown = event.target;
84            startPosX = getPositionX(event);
85            sliderInner.style.transition = 'none';
86            sliderInner.style.cursor = 'grabbing';
87            cancelAnimationFrame(animationID);
88
89            const currentTransform = window.getComputedStyle(sliderInner).getPropertyValue('transform');
90            if (currentTransform !== 'none') {
91                const matrix = currentTransform.match(/^matrix\((.+)\)$/);
92                if (matrix) {
93                    prevTranslate = parseInt(matrix[1].split(', ')[4]);
94                }
95            }
96
97            if (event.type === 'touchstart') {
98                event.preventDefault();
99            }
100
101            if (isDragging) event.preventDefault();
102        }
103    }
104
105    function drag(event) {
106        if (isDragging) {
107            event.preventDefault();
108            const currentPosition = getPositionX(event);
109            currentTranslate = prevTranslate + currentPosition - startPosX;
110
111            // Ограничиваем перемещение
112            const maxTranslate = 0;
113            const minTranslate = -(slides.length - visibleSlides) * totalSlideWidth;
114            currentTranslate = Math.min(Math.max(currentTranslate, minTranslate), maxTranslate);
115
116            sliderInner.style.transform = `translate3d(${currentTranslate}px, 0px, 0px)`;
117            wasDragging = true;
118        }
119    }
120
121    function endDrag(e) {
122        if (isDragging) {
123            isDragging = false;
124            targetUp = e.target;
125            const movedBy = currentTranslate - prevTranslate;
126            sliderInner.style.cursor = '';
127
128            if (movedBy < -50 && currentSlide < slides.length - visibleSlides) {
129                currentSlide++;
130            } else if (movedBy > 50 && currentSlide > 0) {
131                currentSlide--;
132            }
133
134            updateSlider();
135        }
136    }
137
138    function fixHrefBug(e) {
139        let a = targetDown === targetUp;
140        let b = targetUp?.closest('[href]');
141        let c = targetDown?.closest('[href]');
142        if ((a || b || c) && wasDragging)
143            e.preventDefault();
144        wasDragging = false;
145    }
146
147    sliderInner.addEventListener('mousedown', startDrag);
148    window.addEventListener('mousemove', drag);
149    window.addEventListener('mouseup', endDrag);
150    window.addEventListener('click', fixHrefBug)
151
152    // Обработка свайпов для мобильных устройств
153    let touchStartX = 0;
154    let touchEndX = 0;
155
156    sliderInner.addEventListener('touchstart', function(event) {
157        if (window.innerWidth <= 1100) {
158            touchStartX = event.touches[0].clientX;
159        } else {
160            startDrag(event);
161        }
162    });
163
164    sliderInner.addEventListener('touchmove', function(event) {
165        if (window.innerWidth <= 1100) {
166            touchEndX = event.touches[0].clientX;
167        } else {
168            drag(event);
169            event.preventDefault();
170        }
171    });
172
173    sliderInner.addEventListener('touchend', function(e) {
174        if (window.innerWidth <= 1100) {
175            handleSwipe();
176        } else {
177            endDrag(e);
178        }
179    });
180
181    function handleSwipe() {
182        const swipeThreshold = 50;
183        if (touchStartX - touchEndX > swipeThreshold) {
184            if (currentSlide < slides.length - visibleSlides) {
185                currentSlide++;
186                updateSlider();
187            }
188        } else if (touchEndX - touchStartX > swipeThreshold) {
189            if (currentSlide > 0) {
190                currentSlide--;
191                updateSlider();
192            }
193        }
194    }
195
196    // Инициализация
197    updateSlider();
198
199    window.addEventListener('resize', function() {
200        if (window.innerWidth <= 1100) {
201            sliderInner.style.overflowX = 'auto';
202        } else {
203            sliderInner.style.overflowX = 'visible';
204            updateSlider();
205        }
206    });
207
208    if (window.innerWidth <= 1100) {
209        sliderInner.style.overflowX = 'auto';
210    } else {
211        sliderInner.style.overflowX = 'visible';
212    }
213});
214
215(function getFinalScrollPositionAndLinkClick() {
216    function getFinalScrollPosition(scrollTarget) {
217        const currentScroll = window.pageYOffset || document.documentElement.scrollTop;
218        const elementPositionInWindow = scrollTarget.getBoundingClientRect().top;
219        const targetPosition = elementPositionInWindow + currentScroll;
220
221        const headerHeight = 80;
222        const margin = 0;
223        const addedSize = headerHeight ? headerHeight : 0;
224        const finalScrollPosition =
225            elementPositionInWindow - addedSize - margin;
226
227        return finalScrollPosition;
228    }
229
230    document.querySelectorAll('a[href^="#"], .hotel-rate-reviews[href^="#"]').forEach(link => {
231        if (link.getAttribute('href').length > 1) {
232            link.addEventListener('click', function (e) {
233                e.preventDefault();
234                let href = this.getAttribute('href').substring(1);
235
236                const scrollTarget = document.getElementById(href);
237                if (scrollTarget) {
238                    const finalScrollPosition = getFinalScrollPosition(scrollTarget);
239
240                    window.scrollBy({
241                        top: finalScrollPosition,
242                        behavior: 'smooth'
243                    });
244
245                    const tabs = scrollTarget.closest('.tabs-menu');
246                    if (tabs) scrollTarget.click();
247                }
248            });
249        }
250    });
251})();
252
253
254(function() {
255    const sletatContainers = document.querySelectorAll('div[data-sletat-module-id]');
256    if (sletatContainers.length) {
257        const sletatModuleObserver = new MutationObserver(function(mutationsList, observer) {
258            for (const mutation of mutationsList) {
259                if (mutation.addedNodes.length && !mutation.removedNodes.length && mutation.target.querySelectorAll('section.SLT-module6').length) {
260                    let sletatResolved = function(root) {
261                        let resolved = root.querySelector('section.SLT-module6.resolved');
262                        if (resolved) {
263                            const sletatResultsObserver = new MutationObserver(function(mutationsList, observer) {
264                                for (const mutation of mutationsList) {
265                                    if (!mutation.target.classList.contains('SLT-App-red__container')) continue;
266                                    const isOpened = mutation.target.querySelector('.SLT-SearchResults-red__desktopView.SLT-SearchResults-red__container.SLT-SearchResults-red__popUpM
266ode');
267                                    resolved.closest('.inner-wrap-full.content-block').style.zIndex = isOpened ? 99999 : 1;
268                                }
269                            });
270                            sletatResultsObserver.observe(resolved.shadowRoot, {childList: true, subtree: true});
271                        }
272                        else setTimeout(sletatResolved, 50, root);
273                    }
274                    setTimeout(sletatResolved, 150, mutation.target);
275                }
276            }
277        });
278        for (const container of sletatContainers) {
279            sletatModuleObserver.observe(container, {childList: true});
280        }
281    }
282})();

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.