Add 500px prefetch zone for earlier infinite scroll loading
- Add 500px bottom padding when more pages exist (hidden on last page) - Trigger next page load when viewport enters last 500px of content or padding - Add checkImmediateLoad() to chain page loads if viewport still in zone - Runs immediately after page 1 and after each subsequent page loads - Enables rapid sequential loading when user scrolls far or has tall viewport
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
@@ -1162,10 +1162,12 @@
|
|||||||
$grid: null,
|
$grid: null,
|
||||||
$topSentinel: null,
|
$topSentinel: null,
|
||||||
$bottomSentinel: null,
|
$bottomSentinel: null,
|
||||||
|
$bottomPadding: null, // 500px padding when more pages exist
|
||||||
$topLoader: null,
|
$topLoader: null,
|
||||||
$bottomLoader: null,
|
$bottomLoader: null,
|
||||||
topObserver: null,
|
topObserver: null,
|
||||||
bottomObserver: null,
|
bottomObserver: null,
|
||||||
|
prefetchZone: 500, // Pixels from bottom to trigger load
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize infinite scroll
|
* Initialize infinite scroll
|
||||||
@@ -1210,8 +1212,12 @@
|
|||||||
InfiniteScrollState.isEnabled = true;
|
InfiniteScrollState.isEnabled = true;
|
||||||
this.$container.addClass('infinite-scroll-enabled');
|
this.$container.addClass('infinite-scroll-enabled');
|
||||||
|
|
||||||
// Track initial height
|
// Track initial height and update bottom padding
|
||||||
this.updateMaxHeight();
|
this.updateMaxHeight();
|
||||||
|
this.updateBottomPadding();
|
||||||
|
|
||||||
|
// Check if we should immediately load next page (viewport already in trigger zone)
|
||||||
|
this.checkImmediateLoad();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1225,23 +1231,27 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup DOM elements (sentinels and loaders)
|
* Setup DOM elements (sentinels, loaders, and padding)
|
||||||
*/
|
*/
|
||||||
setupDOM: function() {
|
setupDOM: function() {
|
||||||
// Remove any existing infinite scroll elements
|
// Remove any existing infinite scroll elements
|
||||||
this.$container.find('.infinite-scroll-sentinel, .infinite-scroll-loader').remove();
|
this.$container.find('.infinite-scroll-sentinel, .infinite-scroll-loader, .infinite-scroll-padding').remove();
|
||||||
|
|
||||||
// Create top sentinel and loader (before grid)
|
// Create top sentinel and loader (before grid)
|
||||||
this.$topSentinel = $('<div class="infinite-scroll-sentinel" data-direction="top"></div>');
|
this.$topSentinel = $('<div class="infinite-scroll-sentinel" data-direction="top"></div>');
|
||||||
this.$topLoader = $('<div class="infinite-scroll-loader infinite-scroll-loader--top"><div class="spinner"></div></div>');
|
this.$topLoader = $('<div class="infinite-scroll-loader infinite-scroll-loader--top"><div class="spinner"></div></div>');
|
||||||
|
|
||||||
// Create bottom sentinel and loader (after grid)
|
// Create bottom padding (500px zone when more pages exist)
|
||||||
|
this.$bottomPadding = $('<div class="infinite-scroll-padding"></div>');
|
||||||
|
|
||||||
|
// Create bottom sentinel and loader (after grid and padding)
|
||||||
this.$bottomSentinel = $('<div class="infinite-scroll-sentinel" data-direction="bottom"></div>');
|
this.$bottomSentinel = $('<div class="infinite-scroll-sentinel" data-direction="bottom"></div>');
|
||||||
this.$bottomLoader = $('<div class="infinite-scroll-loader infinite-scroll-loader--bottom"><div class="spinner"></div></div>');
|
this.$bottomLoader = $('<div class="infinite-scroll-loader infinite-scroll-loader--bottom"><div class="spinner"></div></div>');
|
||||||
|
|
||||||
// Insert elements
|
// Insert elements: grid -> padding -> loader -> sentinel
|
||||||
this.$grid.before(this.$topSentinel).before(this.$topLoader);
|
this.$grid.before(this.$topSentinel).before(this.$topLoader);
|
||||||
this.$grid.after(this.$bottomLoader).after(this.$bottomSentinel);
|
this.$grid.after(this.$bottomPadding);
|
||||||
|
this.$bottomPadding.after(this.$bottomLoader).after(this.$bottomSentinel);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1325,6 +1335,57 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update bottom padding visibility based on whether more pages exist
|
||||||
|
*/
|
||||||
|
updateBottomPadding: function() {
|
||||||
|
if (!this.$bottomPadding) return;
|
||||||
|
|
||||||
|
var currentPage = InfiniteScrollState.visibleRange.last;
|
||||||
|
var hasMorePages = currentPage < InfiniteScrollState.totalPages;
|
||||||
|
|
||||||
|
if (hasMorePages) {
|
||||||
|
this.$bottomPadding.css('height', this.prefetchZone + 'px');
|
||||||
|
} else {
|
||||||
|
this.$bottomPadding.css('height', '0');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if viewport is already in the prefetch zone and trigger immediate load
|
||||||
|
* Called after any page load completes
|
||||||
|
*/
|
||||||
|
checkImmediateLoad: function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
// Small delay to let DOM settle after render
|
||||||
|
setTimeout(function() {
|
||||||
|
if (!self.$grid || !InfiniteScrollState.isEnabled) return;
|
||||||
|
|
||||||
|
var currentPage = InfiniteScrollState.visibleRange.last;
|
||||||
|
var hasMorePages = currentPage < InfiniteScrollState.totalPages;
|
||||||
|
|
||||||
|
if (!hasMorePages) return;
|
||||||
|
|
||||||
|
// Already loading?
|
||||||
|
var nextPage = currentPage + 1;
|
||||||
|
if (InfiniteScrollState.pendingRequests[nextPage]) return;
|
||||||
|
|
||||||
|
// Check if viewport intersects the prefetch zone
|
||||||
|
// Prefetch zone = last 500px of grid content + 500px padding
|
||||||
|
var gridRect = self.$grid[0].getBoundingClientRect();
|
||||||
|
var viewportBottom = window.innerHeight;
|
||||||
|
|
||||||
|
// Trigger zone starts 500px from bottom of grid content
|
||||||
|
var triggerZoneTop = gridRect.bottom - self.prefetchZone;
|
||||||
|
|
||||||
|
// If viewport bottom is past the trigger zone top, load next page
|
||||||
|
if (viewportBottom >= triggerZoneTop) {
|
||||||
|
self.loadNextPage();
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the next page (append)
|
* Load the next page (append)
|
||||||
*/
|
*/
|
||||||
@@ -1472,6 +1533,9 @@
|
|||||||
// Update max height tracking
|
// Update max height tracking
|
||||||
this.updateMaxHeight();
|
this.updateMaxHeight();
|
||||||
|
|
||||||
|
// Update bottom padding based on whether more pages exist
|
||||||
|
this.updateBottomPadding();
|
||||||
|
|
||||||
// Trigger image lazy loading
|
// Trigger image lazy loading
|
||||||
if (typeof CardImageLoader !== 'undefined') {
|
if (typeof CardImageLoader !== 'undefined') {
|
||||||
CardImageLoader.loadVisibleImages();
|
CardImageLoader.loadVisibleImages();
|
||||||
@@ -1479,6 +1543,9 @@
|
|||||||
|
|
||||||
// Cleanup excess pages
|
// Cleanup excess pages
|
||||||
this.cleanupExcessPages();
|
this.cleanupExcessPages();
|
||||||
|
|
||||||
|
// Check if we should immediately load next page (viewport still in trigger zone)
|
||||||
|
this.checkImmediateLoad();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1680,7 +1747,7 @@
|
|||||||
|
|
||||||
// Remove DOM elements
|
// Remove DOM elements
|
||||||
if (this.$container) {
|
if (this.$container) {
|
||||||
this.$container.find('.infinite-scroll-sentinel, .infinite-scroll-loader').remove();
|
this.$container.find('.infinite-scroll-sentinel, .infinite-scroll-loader, .infinite-scroll-padding').remove();
|
||||||
this.$container.removeClass('infinite-scroll-enabled');
|
this.$container.removeClass('infinite-scroll-enabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -598,6 +598,12 @@
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bottom padding zone (500px when more pages exist)
|
||||||
|
.infinite-scroll-padding {
|
||||||
|
height: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
// Loading indicators
|
// Loading indicators
|
||||||
.infinite-scroll-loader {
|
.infinite-scroll-loader {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
Reference in New Issue
Block a user