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.