PageSourceSearch

https://fortraders.org/wp-content/themes/ForTraderMaster/js/components/itx-latest-posts-inner.js?ver=2.20.34

js fortraders.org collected 2026-10-09 17:31:05 UTC 39,640 bytes, 740 lines download raw bytes

1/**
2 * ITXLatestPostsInner - Компонент для отображения последних постов на внутренних страницах
3 * Показывает 2 карточки на мобильных устройствах
4 */
5
6(function($) {
7    'use strict';
8
9    function ITXLatestPostsInner(options) {
10        this.options = $.extend({
11            container: '.latest-posts-section-inner',
12            paginationSelector: '.pagination-container-inner',
13            dotsSelector: '.pagination-dots-inner',
14            contentSelector: '.latest-posts-grid-inner',
15            cardSelector: '.latest-post-card-inner',
16            maxVisiblePages: 3,
17            swipeThreshold: 50,
18            animationDelay: 100,
19            mobileMaxCards: 2, // Для inner версии показываем 2 карточки
20            ajaxAction: 'load_more_latest_posts_inner',
21            cachePrefix: 'latest-posts-inner_page_'
22        }, options);
23        
24        this.cache = {};
25        this.pagination = {
26            current: 1,
27            total: 1,
28            maxVisible: this.options.maxVisiblePages
29        };
30        
31        this.$container = $(this.options.container);
32        
33        if (this.$container.length === 0) {
34            console.warn('[ITXLatestPostsInner] Container not found:', this.options.container);
35            return;
36        }
37        
38        console.log('[ITXLatestPostsInner] Container found, initializing...');
39        this.init();
40    }
41
42    ITXLatestPostsInner.prototype = {
43        init: function() {
44            // console.log('[ITXLatestPostsInner] Initializing components...');
45            // Добавляем класс js-enabled для применения анимации через CSS
46            this.$container.addClass('js-enabled');
47            
48            this.initPagination();
49            this.initSwipe();
50            this.cacheInitialContent();
51            
52            // Задержка предзагрузки для улучшения LCP
53            var self = this;
54            setTimeout(function() {
55                self.preloadNextPage();
56            }, 2000);
57            
58            this.animateInitialContent();
59            this.initResizeHandler();
60            
61            // Скрываем лишние карточки на мобильных при инициализации
62            this.hideExtraCardsOnMobile();
63            // console.log('[ITXLatestPostsInner] Initialization complete');
64        },
65        
66        // Инициализация пагинации
67        initPagination: function() {
68            var self = this;
69            console.log('[ITXLatestPostsInner] initPagination: Начало инициализации пагинации для внутренних страниц');
70            var $paginationContainer = this.$container.find(this.options.paginationSelector);
71            var $dotsContainer = $paginationContainer.find(this.options.dotsSelector);
72            
73            console.log('[ITXLatestPostsInner] initPagination: Найдены элементы', {
74                paginationContainerExists: $paginationContainer.length > 0,
75                dotsContainerExists: $dotsContainer.length > 0
76            });
77            
78            // Проверяем наличие data-max-pages
79            var maxPagesAttr = $paginationContainer.data('max-pages');
80            if (maxPagesAttr) {
81                this.pagination.total = parseInt(maxPagesAttr);
82                console.log('[ITXLatestPostsInner] initPagination: Используем total из атрибута:', this.pagination.total);
83                
84                // Создаем точки сразу
85                $dotsContainer.empty();
86                var dotsToCreate = Math.min(this.pagination.total, this.pagination.maxVisible);
87                for (var i = 1; i <= dotsToCreate; i++) {
88                    var $dot = $('<div class="pagination-dot-inner" data-page="' + i + '"></div>');
89                    if (i === 1) $dot.addClass('active');
90                    $dotsContainer.append($dot);
91                }
92            } else {
93                // НЕ создаем точки заранее - ждем ответа от сервера
94                $dotsContainer.empty();
95                console.log('[ITXLatestPostsInner] initPagination: Контейнер точек очищен, ждем ответа от сервера');
96                
97                // Запрашиваем реальное количество страниц у сервера
98                this.updateTotalPages();
99            }
100            
101            // Обработчик клика по точкам
102            console.log('[ITXLatestPostsInner] initPagination: Регистрация обработчика кликов');
103            $dotsContainer.on('click', '.pagination-dot-inner', function(e) {
104                console.log('[ITXLatestPostsInner] CLICK: Событие клика зафиксировано!', {
105                    target: e.target,
106                    currentTarget: e.currentTarget,
107                    timestamp: new Date().toISOString()
108                });
109                
110                e.preventDefault();
111                e.stopPropagation();
112                
113                var page = parseInt($(this).data('page'));
114                var $clickedDot = $(this);
115                
116                console.log('[ITXLatestPostsInner] CLICK: Клик по точке пагинации', {
117                    page: page,
118                    isActive: $clickedDot.hasClass('active'),
119                    hasLoading: $clickedDot.hasClass('loading'),
120                    currentPage: self.pagination.current,
121                    total: self.pagination.total
122                });
123                
124                // КРИТИЧНО: Проверяем, что страница не превышает total
125                if (page > self.pagination.total) {
126                    console.warn('[ITXLatestPostsInner] CLICK: Страница превышает total, удаляем точку', {
127                        page: page,
128                        total: self.pagination.total
129                    });
130                    $clickedDot.remove();
131                    return;
132                }
133                
134                if (page && page !== self.pagination.current) {
135                    console.log('[ITXLatestPostsInner] CLICK: Вызов goToPage для страницы', page);
136                    self.goToPage(page, $clickedDot);
137                } else {
138                    console.log('[ITXLatestPostsInner] CLICK: Клик проигнорирован - та же страница или неверный номер');
139                }
140            });
141            
142            console.log('[ITXLatestPostsInner] initPagination: Инициализация пагинации завершена');
143        },
144        
145        // Обновление общего количества страниц из AJAX
146        // v2: language fallback uses <html lang>, not 'ru'
147        updateTotalPages: function() {
148            var self = this;
149            console.log('[ITXLatestPostsInner] updateTotalPages: Запрос информации о количестве страниц');
150            
151            // Получаем nonce и ajaxUrl
152            var nonce = '';
153            var ajaxUrl = '';
154            
155            // Проверяем ITXApp (приоритет)
156            if (typeof ITXApp !== 'undefined') {
157                if (ITXApp.nonce) {
158                    nonce = ITXApp.nonce;
159                }
160                if (ITXApp.ajaxUrl) {
161                    ajaxUrl = ITXApp.ajaxUrl;
162                }
163            }
164            
165            // Fallback на ajax_object
166            if (!nonce && typeof ajax_object !== 'undefined' && ajax_object.nonce) {
167                nonce = ajax_object.nonce;
168            }
169            if (!ajaxUrl && typeof ajax_object !== 'undefined' && ajax_object.ajax_url) {
170                ajaxUrl = ajax_object.ajax_url;
171            }
172            
173            // Если все еще нет URL, используем абсолютный путь
174            if (!ajaxUrl) {
175                // Получаем базовый URL сайта
176                var siteUrl = window.location.protocol + '//' + window.location.host;
177                ajaxUrl = siteUrl + '/wp-admin/admin-ajax.php';
178            }
179            
180            console.log('[ITXLatestPostsInner] updateTotalPages: AJAX настройки', {
181                ajaxUrl: ajaxUrl,
182                nonce: nonce ? 'SET (' + nonce.substring(0, 10) + '...)' : 'NOT SET',
183                action: this.options.ajaxAction,
184                ITXAppExists: typeof ITXApp !== 'undefined',
185                ajax_objectExists: typeof ajax_object !== 'undefined'
186            });
187            
188            var ajaxData = {
189                action: this.options.ajaxAction,
190                page: 1,
191                nonce: nonce,
192                language: window.ITXHomepageUtils ? window.ITXHomepageUtils.getCurrentLanguage() : ((document.documentElement.lang || '').slice(0, 2).toLowerCase() || 'en')
193            };
194            
195            console.log('[ITXLatestPostsInner] updateTotalPages: AJAX данные', ajaxData);
196            
197            $.ajax({
198                url: ajaxUrl,
199                type: 'POST',
200                timeout: 10000,
201                cache: false,
202                data: ajaxData,
203                success: function(response) {
204                    console.log('[ITXLatestPostsInner] updateTotalPages: Ответ от сервера', {
205                        success: response.success,
206                        max_pages: response.data ? response.data.max_pages : 'undefined',
207                        has_more: response.data ? response.data.has_more : 'undefined',
208                        current_page: response.data ? response.data.current_page : 'undefined'
209                    });
210                    
211                    if (response.success && response.data.max_pages) {
212                        var maxPages = response.data.max_pages;
213                        var oldTotal = self.pagination.total;
214                        self.pagination.total = maxPages;
215                        
216                        console.log('[ITXLatestPostsInner] updateTotalPages: Обновлено количество страниц', {
217                            oldTotal: oldTotal,
218                            newTotal: maxPages,
219                            changed: oldTotal !== maxPages
220                        });
221                        
222                        // Создаем точки на основе реального количества страниц
223                        var $paginationContainer = self.$container.find(self.options.paginationSelector);
224                        var $dotsContainer = $paginationContainer.find(self.options.dotsSelector);
225                        
226                        // Очищаем контейнер и создаем правильное количество точек
227                        $dotsContainer.empty();
228                        var dotsToCreate = Math.min(maxPages, self.pagination.maxVisible);
229                        
230                        console.log('[ITXLatestPostsInner] updateTotalPages: Создание точек', {
231                            maxPages: maxPages,
232                            maxVisible: self.pagination.maxVisible,
233                            dotsToCreate: dotsToCreate
234                        });
235                        
236                        for (var i = 1; i <= dotsToCreate; i++) {
237                            var $dot = $('<div class="pagination-dot-inner" data-page="' + i + '"></div>');
238                            if (i === 1) {
239                                $dot.addClass('active');
240                            }
241                            $dotsContainer.append($dot);
242                        }
243                        
244                        // Устанавливаем активную точку
245                        self.pagination.current = 1;
246                        var activeDots = $dotsContainer.find('.pagination-dot-inner.active');
247                        console.log('[ITXLatestPostsInner] updateTotalPages: Точки созданы', {
248                            total: self.pagination.total,
249                            current: self.pagination.current,
250                            activeDot: activeDots.length,
251                            totalDots: $dotsContainer.find('.pagination-dot-inner').length,
252                            activeDotExists: activeDots.length > 0
253                        });
254                        
255                        // Если активная точка не установлена, устанавливаем вручную
256                        if (activeDots.length === 0 && dotsToCreate > 0) {
257                            console.log('[ITXLatestPostsInner] updateTotalPages: Активная точка не найдена, устанавливаем вручную');
258                            $dotsContainer.find('.pagination-dot-inner[data-
258page="1"]').addClass('active');
259                        }
260                    } else {
261                        console.warn('[ITXLatestPostsInner] updateTotalPages: Не удалось получить max_pages из ответа');
262                    }
263                },
264                error: function(xhr, status, error) {
265                    console.error('[ITXLatestPostsInner] updateTotalPages: Ошибка AJAX', {status: status, error: error});
266                }
267            });
268        },
269        
270        // Переход на страницу
271        goToPage: function(page, $dot) {
272            console.log('[ITXLatestPostsInner] goToPage: Переход на страницу', {
273                page: page,
274                currentBefore: this.pagination.current,
275                total: this.pagination.total
276            });
277            
278            // КРИТИЧНО: Проверяем, что страница не превышает total
279            if (page > this.pagination.total) {
280                console.warn('[ITXLatestPostsInner] goToPage: Страница превышает total, отмена перехода', {
281                    page: page,
282                    total: this.pagination.total
283                });
284                return;
285            }
286            
287            var $paginationContainer = this.$container.find(this.options.paginationSelector);
288            var $contentContainer = this.$container.find(this.options.contentSelector);
289            var $dotsContainer = $paginationContainer.find(this.options.dotsSelector);
290            var cacheKey = this.options.cachePrefix + page;
291            
292            // Если $dot не передан, находим его
293            if (!$dot) {
294                $dot = $dotsContainer.find('.pagination-dot-inner[data-page="' + page + '"]');
295            }
296            
297            // Обновляем активную точку
298            $dotsContainer.find('.pagination-dot-inner').removeClass('active');
299            $dot.addClass('active');
300            
301            // Обновляем состояние
302            this.pagination.current = page;
303            // console.log('[ITXLatestPostsInner] Current page updated to:', this.pagination.current);
304            
305            // Проверяем кэш
306            // console.log('[ITXLatestPostsInner] Checking cache for key:', cacheKey, 'Exists:', !!this.cache[cacheKey]);
307            if (this.cache[cacheKey]) {
308                // Используем кэш - с плавным переходом
309                // console.log('[ITXLatestPostsInner] Using cached content');
310                this.smoothTransition($contentContainer, this.cache[cacheKey]);
311                this.preloadNextPage();
312            } else {
313                // Загружаем через AJAX
314                // console.log('[ITXLatestPostsInner] Cache miss, loading via AJAX');
315                $dot.addClass('loading');
316                $contentContainer.addClass('loading');
317                this.loadPage(page, $dot, $contentContainer, $dotsContainer);
318            }
319        },
320        
321        // Загрузка страницы через AJAX
322        // v2: language fallback uses <html lang>, not 'ru'
323        loadPage: function(page, $dot, $container, $dotsContainer) {
324            var self = this;
325            // console.log('[ITXLatestPostsInner] loadPage called for page:', page);
326            // console.log('[ITXLatestPostsInner] Checking ITXApp.getService("ajax"):', typeof ITXApp !== 'undefined' && ITXApp.getService('ajax'));
327            
328            if (typeof ITXApp !== 'undefined' && ITXApp.getService('ajax')) {
329                // console.log('[ITXLatestPostsInner] Using ITXApp.getService("ajax").loadLatestPostsInner');
330                ITXApp.getService('ajax').loadLatestPostsInner(page, {
331                    success: function(response) {
332                        // console.log('[ITXLatestPostsInner] AJAX Success response:', response);
333                        $container.removeClass('loading');
334                        
335                        if (response.success && response.data.html) {
336                            console.log('[ITXLatestPostsInner] loadPage: Ответ получен', {
337                                page: page,
338                                hasHtml: !!(response.data.html),
339                                max_pages: response.data ? response.data.max_pages : 'undefined',
340                                has_more: response.data ? response.data.has_more : 'undefined',
341                                current_page: response.data ? response.data.current_page : 'undefined'
342                            });
343                            
344                            // Обновляем общее количество страниц из ответа
345                            if (response.data.max_pages) {
346                                var oldTotal = self.pagination.total;
347                                self.pagination.total = response.data.max_pages;
348                                
349                                console.log('[ITXLatestPostsInner] loadPage: Обновлено количество страниц', {
350                                    oldTotal: oldTotal,
351                                    newTotal: response.data.max_pages,
352                                    changed: oldTotal !== response.data.max_pages
353                                });
354                                
355                                // Удаляем лишние точки
356                                var removedCount = 0;
357                                $dotsContainer.find('.pagination-dot-inner').each(function() {
358                                    var dotPage = parseInt($(this).data('page'));
359                                    if (dotPage > self.pagination.total) {
360                                        $(this).remove();
361                                        removedCount++;
362                                    }
363                                });
364                                
365                                if (removedCount > 0) {
366                                    console.log('[ITXLatestPostsInner] loadPage: Удалено лишних точек', removedCount);
367                                }
368                            }
369                            
370                            // Кэшируем данные
371                            var cacheKey = self.options.cachePrefix + page;
372                            self.cache[cacheKey] = response.data.html;
373                            
374                            // Обновляем контент с плавным переходом
375                            self.smoothTransition($container, response.data.html);
376                            $dot.removeClass('loading');
377                            
378                            // ВАЖНО: Обновляем currentPage после успешной загрузки
379                            self.pagination.current = page;
380                            
381                            // Добавляем точку для следующей страницы если есть контент И не превышаем max_pages
382                            // ВАЖНО: Проверяем что следующая страница не превышает total
383                            var nextPage = page + 1;
384                            var shouldAddDot = response.data.has_more && page >= self.pagination.maxVisible && nextPage <= self.pagination.total;
385                            
386                            console.log('[ITXLatestPostsInner] loadPage: Проверка добавления точки', {
387                                has_more: response.data.has_more,
388                                page: page,
389                                nextPage: nextPage,
390                                maxVisible: self.pagination.maxVisible,
391                                total: self.pagination.total,
392                                shouldAddDot: shouldAddDot
393                            });
394                            
395                            if (shouldAddDot) {
396                                self.addDot(nextPage);
397                            } else {
398                                console.log('[ITXLatestPostsInner] loadPage: Точка НЕ добавлена', {
399                                    reason: !response.data.has_more ? 'has_more=false' : 
400                                            page < self.pagination.maxVisible ? 'page < maxVisible' : 
401                                            nextPage > self.pagination.total ? 'nextPage > total' : 'unknown'
402                                });
403                            }
404                            
405                            // Предзагружаем следующую страницу
406                            self.preloadNextPage();
407                        } else {
408                            console.warn('[ITXLatestPostsInner] Response invalid:', response);
409                            self.revertToFirstPage($dotsContainer, $dot);
410                        }
411                    },
412                    error: function(xhr, status, error) {
413                        $container.removeClass('loading');
414                        $dot.removeClass('loading');
415                        console.error('[ITXLatestPostsInner] AJAX Error:', error, 'Status:', status, 'XHR:', xhr.responseText ? xhr.responseText.substring(0, 100) : '');
416                        self.revertToFirstPage($dotsContainer, $dot);
417                    }
418                });
419            } else {
420                // Fallback AJAX call
421                // console.log('[ITXLatestPostsInner] Using fallback $.ajax method');
422                // console.log('[ITXLatestPostsInner] AJAX URL:', ITXApp.ajaxUrl, 'Action:', self.options.ajaxAction);
423                $.ajax({
424                    url: ITXApp.ajaxUrl,
425                    type: 'POST',
426                    data: {
427                        action: self.options.ajaxAction,
428                        page: page,
429                        nonce: ITXApp.nonce,
430                        language: window.ITXHomepageUtils ? window.ITXHomepageUtils.getCurrentLanguage() : ((document.documentElement.lang || '').slice(0, 2).toLowerCase() || 'en')
431                    },
432                    success: function(response) {
433                        // console.log('[ITXLatestPostsInner] Fallback AJAX Success response:', response);
434                        $container.removeClass('loading');
435                        $dot.removeClass('loading');
436                        
437                        if (response.success && response.data.html) {
438                            console.log('[ITXLatestPostsInner] loadPage (fallback): Ответ получен', {
439                                page: page,
440                                hasHtml: !!(response.data.html),
441                                max_pages: response.data ? response.data.max_pages : 'undefined',
442                                has_more: response.data ? response.data.has_more : 'undefined'
443                            });
444                            
445                            // Обновляем общее количество страниц из ответа
446                            if (response.data.max_pages) {
447                                var oldTotal = self.pagination.total;
448                                self.pagination.total = response.data.max_pages;
449                                
450                                console.log('[ITXLatestPostsInner] loadPage (fallback): Обновлено количество страниц', {
451                                    oldTotal: oldTotal,
452                                    newTotal: response.data.max_pages
453                                });
454                                
455                                // Удаляем лишние точки
456                                $dotsContainer.find('.pagination-dot-inner').each(function() {
457                                    var dotPage = parseInt($(this).data('page'));
458                                    if (dotPage > self.pagination.total) {
459                                        $(this).remove();
460                                    }
461                                });
462                            }
463                            
464                            var cacheKey = self.options.cachePrefix + page;
465                            self.cache[cacheKey] = response.data.html;
466                            
467                            self.smoothTransition($container, response.data.html);
468                            
469                            // ВАЖНО: Обновляем currentPage после успешной загрузки
470                            self.pagination.current = page;
471                            
472                            // Добавляем точку для следующей страницы если есть контент И не превышаем max_pages
473                            var nextPage = page + 1;
474                            var shouldAddDot = response.data.has_more && page >= self.pagination.maxVisible && nextPage <= self.pagination.total;
475                            
476                            if (shouldAddDot) {
477                                self.addDot(nextPage);
478                            }
479                            
480                            self.preloadNextPage();
481                        } else {
482                            console.warn('[ITXLatestPostsInner] Fallback response invalid:', response);
483                            self.revertToFirstPage($dotsContainer, $dot);
484                        }
485                    },
486                    error: function(xhr, status, error) {
487                        $container.removeClass('loading');
488                        $dot.removeClass('loading');
489                        console.error('[ITXLatestPostsInner] Fallback AJAX Error:', error, 'Status:', status, 'XHR:', xhr.responseText ? xhr.responseText.substring(0, 100) : '');
490                        self.revertToFirstPage($dotsContainer, $dot);
491                    }
492                });
493            }
494        },
495        
496        // Добавление новой точки
497        addDot: function(pageNumber) {
498            console.log('[ITXLatestPostsInner] addDot: Попытка создания точки', {
499                pageNumber: pageNumber,
500                currentTotal: this.pagination.total,
501                currentPage: this.pagination.current
502            });
503            
504            var $paginationContainer = this.$container.find(this.options.paginationSelector);
505            var $dotsContainer = $paginationContainer.find(this.options.dotsSelector);
506            
507            // Проверяем, не существует ли уже такая точка
508            if ($dotsContainer.find('.pagination-dot-inner[data-
508page="' + pageNumber + '"]').length > 0) {
509                console.log('[ITXLatestPostsInner] addDot: Точка уже существует, выход');
510                return;
511            }
512            
513            // КРИТИЧНО: Проверяем, что страница не превышает максимум
514            if (pageNumber > this.pagination.total) {
515                console.warn('[ITXLatestPostsInner] addDot: Точка НЕ создана - превышает максимум', {
516                    pageNumber: pageNumber,
517                    total: this.pagination.total,
518                    reason: 'pageNumber > total'
519                });
520                return;
521            }
522            
523            var $newDot = $('<div class="pagination-dot-inner" data-page="' + pageNumber + '"></div>');
524            
525            $newDot.css({
526                'opacity': '0',
527                'transform': 'scale(0.3)'
528            });
529            
530            $dotsContainer.append($newDot);
531            
532            setTimeout(function() {
533                $newDot.css({
534                    'opacity': '1',
535                    'transform': 'scale(1)',
536                    'transition': 'all 0.6s cubic-bezier(0.4, 0, 0.2, 1)'
537                });
538            }, 100);
539            
540            var dotsCount = $dotsContainer.find('.pagination-dot-inner').length;
541            console.log('[ITXLatestPostsInner] addDot: Точка создана', {
542                pageNumber: pageNumber,
543                totalDots: dotsCount,
544                total: this.pagination.total
545            });
546        },
547        
548        // Обновление активной точки пагинации
549        updateActiveDot: function() {
550            var $paginationContainer = this.$container.find(this.options.paginationSelector);
551            var $dotsContainer = $paginationContainer.find(this.options.dotsSelector);
552            
553            // Убираем активный класс со всех точек
554            $dotsContainer.find('.pagination-dot-inner').removeClass('active');
555            
556            // Добавляем активный класс к текущей странице
557            $dotsContainer.find('.pagination-dot-inner[data-page="' + this.pagination.current + '"]').addClass('active');
558        },
559        
560        // Предзагрузка следующей страницы
561        preloadNextPage: function() {
562            var self = this;
563            var nextPage = this.pagination.current + 1;
564            var cacheKey = this.options.cachePrefix + nextPage;
565            
566            if (!this.cache[cacheKey] && typeof ITXApp !== 'undefined' && ITXApp.getService('ajax')) {
567                ITXApp.getService('ajax').loadLatestPostsInner(nextPage, {
568                    success: function(response) {
569                        if (response.success && response.data.html) {
570                            self.cache[cacheKey] = response.data.html;
571                        }
572                    }
573                });
574            }
575        },
576        
577        // Кэширование начального контента
578        cacheInitialContent: function() {
579            var $contentContainer = this.$container.find(this.options.contentSelector);
580            var cacheKey = this.options.cachePrefix + '1';
581            this.cache[cacheKey] = $contentContainer.html();
582        },
583        
584        // Возврат к первой странице
585        revertToFirstPage: function($dotsContainer, $dot) {
586            $dot.removeClass('loading');
587            this.goToPage(1);
588        },
589        
590        // Плавный переход между страницами
591        smoothTransition: function($container, newContent) {
592            var self = this;
593            // console.log('[ITXLatestPostsInner] smoothTransition called. Container:', $container.length, 'Content length:', newContent ? newContent.length : 0);
594            
595            // Добавляем класс перехода
596            $container.addClass('transitioning');
597            // console.log('[ITXLatestPostsInner] Added transitioning class');
598            
599            // Ждем завершения анимации исчезновения
600            setTimeout(function() {
601                // console.log('[ITXLatestPostsInner] Updating container HTML...');
602                // Обновляем контент
603                $container.html(newContent);
604                // console.log('[ITXLatestPostsInner] Container HTML updated');
605                
606                // Убираем класс перехода
607                $container.removeClass('transitioning');
608                // console.log('[ITXLatestPostsInner] Removed transitioning class');
609                
610                // Обновляем активную точку пагинации
611                self.updateActiveDot();
612                // console.log('[ITXLatestPostsInner] Active dot updated');
613                
614                // Небольшая задержка для плавности
615                setTimeout(function() {
616                    // console.log('[ITXLatestPostsInner] Animating initial content...');
617                    // Анимируем появление нового контента
618                    self.animateInitialContent();
619                }, 50);
620            }, 400);
621        },
622        
623        // Анимация контента
624        animateInitialContent: function() {
625            var self = this;
626            this.$container.find(this.options.cardSelector).each(function(index) {
627                var $card = $(this);
628                setTimeout(function() {
629                    $card.addClass('animate-in');
630                }, index * self.options.animationDelay);
631            });
632            
633            // Скрываем лишние карточки на мобильных устройствах
634            this.hideExtraCardsOnMobile();
635        },
636        
637        // Скрытие лишних карточек на мобильных устройствах
638        hideExtraCardsOnMobile: function() {
639            var self = this;
640            var $cards = this.$container.find(this.options.cardSelector);
641            var isMobile = window.innerWidth <= 768;
642            
643            // Небольшая задержка для корректной работы
644            setTimeout(function() {
645                $cards.each(function(index) {
646                    var $card = $(this);
647                    if (isMobile) {
648                        // На мобильных показываем только первые mobileMaxCards карточек
649                        if (index >= self.options.mobileMaxCards) {
650                            $card.hide();
651                        } else {
652                            $card.show();
653                        }
654                    } else {
655                        // На десктопе показываем только первые 4 карточки
656                        if (index < 4) {
657                            $card.show();
658                        } else {
659                            $card.hide();
660                        }
661                    }
662                });
663            }, 100);
664        },
665        
666        // Обработчик изменения размера окна
667        initResizeHandler: function() {
668            var self = this;
669            var resizeTimeout;
670            
671            $(window).on('resize', function() {
672                clearTimeout(resizeTimeout);
673                resizeTimeout = setTimeout(function() {
674                    self.hideExtraCardsOnMobile();
675                }, 250);
676            });
677        },
678        
679        // Инициализация свайпов
680        initSwipe: function() {
681            var self = this;
682            var startX = 0, startY = 0, endX = 0, endY = 0;
683            
684            // console.log('[ITXLatestPostsInner] Initializing swipe on container:', this.$container);
685            
686            this.$container.on('touchstart', function(e) {
687                var touch = e.originalEvent.touches[0];
688                startX = touch.clientX;
689                startY = touch.clientY;
690                // console.log('[ITXLatestPostsInner] Touch start:', startX, startY);
691            });
692            
693            this.$container.on('touchend', function(e) {
694                var touch = e.originalEvent.changedTouches[0];
695                endX = touch.clientX;
696                endY = touch.clientY;
697                
698                var deltaX = endX - startX;
699                var deltaY = endY - startY;
700                
701                // console.log('[ITXLatestPostsInner] Touch end:', endX, endY, 'delta:', deltaX, deltaY);
702                
703                if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > self.options.swipeThreshold) {
704                    // console.log('[ITXLatestPostsInner] Swipe detected:', deltaX > 0 ? 'right' : 'left');
705                    
706                    var $paginationContainer = self.$container.find(self.options.paginationSelector);
707                    var $dotsContainer = $paginationContainer.find(self.options.dotsSelector);
708                    var $activeDot = $dotsContainer.find('.pagination-dot-inner.active');
709                    var currentPage = parseInt($activeDot.data('page'));
710                    
711                    // console.log('[ITXLatestPostsInner] Current page:', currentPage, 'Total pages:', self.pagination.total);
712                    
713                    if (deltaX > 0 && currentPage > 1) {
714                        // Свайп вправо - предыдущая страница
715                        // console.log('[ITXLatestPostsInner] Going to previous page:', currentPage - 1);
716                        var $prevDot = $dotsContainer.find('.pagination-dot-inner[data-
716page="' + (currentPage - 1) + '"]');
717                        self.goToPage(currentPage - 1, $prevDot);
718                    } else if (deltaX < 0 && currentPage < self.pagination.total) {
719                        // Свайп влево - следующая страница
720                        // console.log('[ITXLatestPostsInner] Going to next page:', currentPage + 1);
721                        var $nextDot = $dotsContainer.find('.pagination-dot-inner[data-page="' + (currentPage + 1) + '"]');
722                        if ($nextDot.length === 0) {
723                            self.addDot(currentPage + 1);
724                            $nextDot = $dotsContainer.find('.pagination-dot-inner[data-page="' + (currentPage + 1) + '"]');
725                        }
726                        self.goToPage(currentPage + 1, $nextDot);
727                    } else {
728                        // console.log('[ITXLatestPostsInner] Swipe ignored - no valid page to go to');
729                    }
730                } else {
731                    // console.log('[ITXLatestPostsInner] Swipe ignored - not horizontal enough or below threshold');
732                }
733            });
734        }
735    };
736
737    // Экспорт в глобальную область
738    window.ITXLatestPostsInner = ITXLatestPostsInner;
739
740})(jQuery);

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.