jQuery(document).ready(function($) { var $container = $('.responsive-grid-container'); if (!$container.length) return; // Exit early if the shortcode structure is not on page template var $grid = $('#wp-custom-post-grid'); var $sentinel = $('#infinite-scroll-sentinel'); var $filterMenu = $('#grid-category-filters'); var maxPages = parseInt($grid.data('max-pages')); var ppp = parseInt($container.data('ppp')) || 6; // Dynamic capture from data attributes var isFetching = false; // FIX: JavaScript is active, so safely make the infinite scroll tracker visible now $sentinel.css('display', 'flex'); var observer = new IntersectionObserver(function(entries) { entries.forEach(function(entry) { if (entry.isIntersecting && !isFetching) { loadMorePosts(); } }); }, { rootMargin: '400px' }); if (maxPages > 1) { observer.observe($sentinel[0]); } // Category click handler with URL history persistence // Category click handler supporting clean, non-stacking directory switches $filterMenu.on('click', '.filter-item', function(e) { e.preventDefault(); var $clicked = $(this); if ($clicked.hasClass('active') || isFetching) return; $('.filter-item').removeClass('active'); $clicked.addClass('active'); var newCatID = $clicked.data('category'); var catSlug = $clicked.data('slug'); // FIX: Pull the frozen base url from data attributes instead of browser history path arrays var basePageURL = $container.data('base-url'); var newURL = basePageURL; // Guarantee a unified single trailing slash architecture if (!newURL.endsWith('/')) { newURL += '/'; } // If managing an active core /category/ archive url structure path if (window.location.pathname.includes('/category/')) { if (catSlug) { newURL = window.location.origin + '/category/' + catSlug + '/'; } else { newURL = basePageURL; // Clicking "All" sends them back to your clean base shortcode page } } // FIX: If managing an active core /tag/ archive page, route cleanly out of it when changing categories else if (window.location.pathname.includes('/tag/')) { if (catSlug) { newURL = basePageURL + catSlug + '/'; // Route back to the blog's dynamic subdirectories } else { newURL = basePageURL; // Clicking "All" brings them straight back to the root blog index } } else { // Standard Page code path framework swapping rules if (catSlug) { newURL += catSlug + '/'; } } window.history.pushState({ path: newURL }, '', newURL); $sentinel.data('page', 0); $sentinel.data('category', newCatID); $grid.html(''); observer.disconnect(); loadMorePosts(true); }); function loadMorePosts(isNewFilter = false) { var currentPage = parseInt($sentinel.data('page')); var nextPage = currentPage + 1; var currentCat = $sentinel.data('category'); var currentTag = $sentinel.data('tag'); // Read tag data-attribute from html if (!isNewFilter && nextPage > maxPages) { return; } isFetching = true; $sentinel.show().addClass('is-loading'); // Update this variable lookup inside loadMorePosts(): var currentSearch = $sentinel.data('search') || ''; $.ajax({ url: wp_grid_params.ajaxurl, type: 'POST', dataType: 'json', data: { action: 'load_more_posts', page: nextPage, ppp: ppp, category: currentCat, tag: currentTag, search: currentSearch, is_global_search: new URLSearchParams(window.location.search).has('s') ? '1' : '0' }, success: function(response) { if (response.html.trim() !== '') { var $html = $(response.html); $html.css('opacity', 0); $grid.append($html); $html.each(function(i) { var $el = $(this); setTimeout(function() { $el.css('opacity', 1); }, i * 80); }); $sentinel.data('page', nextPage); maxPages = parseInt(response.max_pages); isFetching = false; $sentinel.removeClass('is-loading'); if (nextPage >= maxPages) { $sentinel.hide(); } else { observer.observe($sentinel[0]); } } else { isFetching = false; $sentinel.removeClass('is-loading').hide(); } }, error: function() { isFetching = false; $sentinel.removeClass('is-loading'); } }); } // FORCE INITIAL RUN: Override theme scripts right after execution paint threads setTimeout(function() { window.dispatchEvent(new Event('resize')); $(window).trigger('scroll'); // Safety step: Convert jQuery wrapper safely into raw DOM token node if ($sentinel.length && !isFetching) { var sentinelNativeNode = $sentinel[0]; // Convert jQuery pointer to raw HTML Node object var sentinelPos = sentinelNativeNode.getBoundingClientRect(); if (sentinelPos.top < window.innerHeight + 400) { loadMorePosts(); } } }, 400); // Increased slightly to 400ms to allow theme layout scripts to finish firing first // PERFORMANCE-OPTIMISED DIRECTION WATCHER (Mobile Only) var lastScroll = 0; var filterElement = document.getElementById('grid-category-filters'); if (filterElement) { window.addEventListener('scroll', function() { // Instantly skip processing if on a tablet/desktop screen if (window.innerWidth >= 768) return; var currentScroll = window.pageYOffset || document.documentElement.scrollTop; // Micro-buffer optimization: Don't flip states for tiny 5px movements if (Math.abs(currentScroll - lastScroll) < 8) return; if (currentScroll > 150 && currentScroll > lastScroll) { // Direction: Down -> Inject class natively bypasses jQuery lookup arrays filterElement.classList.add('filters-hidden'); } else { // Direction: Up -> Re-display filters panel instantly filterElement.classList.remove('filters-hidden'); } lastScroll = currentScroll <= 0 ? 0 : currentScroll; // Mobile bounce buffer safety }, { passive: true }); // 'passive: true' tells the browser it won't block screen paint speeds } // SEARCH ENGINE: Live search input processing with debouncing var searchTimeout; var $searchInput = $('#grid-search-input'); var $searchClear = $('.search-clear-icon'); $searchInput.on('keyup input', function() { var $input = $(this); var query = $input.val().trim(); // Add these lines right inside your existing $('#grid-search-input').on('keyup input', ...) loop: if (query.length > 0) { $searchClear.show(); $input.parent('.grid-search-wrapper').addClass('has-input'); // Keeps search expanded if text exists } else { $searchClear.hide(); $input.parent('.grid-search-wrapper').removeClass('has-input'); } // Clear existing keystroke timeouts to protect server performance clearTimeout(searchTimeout); searchTimeout = setTimeout(function() { var currentCatSlug = $('#grid-category-filters .filter-item.active').data('slug') || ''; var basePageURL = $container.data('base-url'); var newURL = basePageURL; if (!newURL.endsWith('/')) { newURL += '/'; } if (currentCatSlug) { newURL += currentCatSlug + '/'; } // Dynamic URL string generation including search parameters if (query.length > 0) { newURL += '?grid_search=' + encodeURIComponent(query); } window.history.pushState({ path: newURL }, '', newURL); // Reset pagination parameters for a fresh search execution loop $sentinel.data('page', 0); $sentinel.data('search', query); $grid.html(''); observer.disconnect(); loadMorePosts(true); }, 400); // Wait 400ms after user stops typing before query execution }); // Clear search button behavior $searchClear.on('click', function() { $searchInput.val('').trigger('keyup'); }); // DESKTOP INTERFACE: Convert vertical mouse scroll-wheel movements into smooth horizontal tray swiping $(document).on('wheel', '.related-footer-matrix', function(e) { // Prevent default window page vertical scroll movement when browsing the horizontal tray e.preventDefault(); var delta = e.originalEvent.deltaY; // Adjust standard scroll speed multiplier parameter settings smoothly this.scrollLeft += (delta * 1.5); }); }); https://www.theredpeach.co.uk/post-sitemap.xml 2026-09-21T01:02:10+00:00 https://www.theredpeach.co.uk/page-sitemap.xml 2026-09-24T19:56:34+00:00 https://www.theredpeach.co.uk/product-sitemap.xml 2026-08-29T09:29:16+00:00 https://www.theredpeach.co.uk/elementor-hf-sitemap.xml 2026-09-24T22:54:01+00:00 https://www.theredpeach.co.uk/category-sitemap.xml 2026-09-21T01:02:10+00:00 https://www.theredpeach.co.uk/post_tag-sitemap.xml 2026-09-21T01:02:10+00:00 https://www.theredpeach.co.uk/product_cat-sitemap.xml 2026-08-29T09:29:16+00:00 https://www.theredpeach.co.uk/product_tag-sitemap.xml 2026-08-29T09:29:16+00:00 https://www.theredpeach.co.uk/author-sitemap.xml 2026-08-04T18:42:52+00:00