Files
blog/themes/Ying/assets/js/modules/lazyload.js
T

121 lines
3.6 KiB
JavaScript
Raw Normal View History

2026-01-31 19:24:22 +08:00
(function() {
2026-02-02 20:38:58 +08:00
// Default configuration
2026-01-31 19:24:22 +08:00
var defaults = {
2026-02-02 20:38:58 +08:00
offsetBottom: 100, // Distance from bottom to start loading
showTime: 1100, // Transition duration (ms)
queueInterval: 200 // Time between showing successive images in queue
2026-01-31 19:24:22 +08:00
};
var observer;
2026-02-02 20:38:58 +08:00
var imageQueue = []; // Queue for images waiting to be shown
var isProcessingQueue = false;
2026-01-31 19:24:22 +08:00
function init(setting) {
2026-02-02 20:38:58 +08:00
// Merge settings
2026-01-31 19:24:22 +08:00
defaults = Object.assign({}, defaults, setting || {});
2026-02-02 20:38:58 +08:00
// Reset queue
imageQueue = [];
isProcessingQueue = false;
// Disconnect previous observer if exists (for PJAX)
2026-01-31 21:27:06 +08:00
if (observer) {
observer.disconnect();
observer = null;
2026-01-31 19:24:22 +08:00
}
2026-02-02 20:38:58 +08:00
// Check for IntersectionObserver support
if (!window.IntersectionObserver) {
loadAllImages();
return;
}
2026-01-31 21:27:06 +08:00
// Initialize IntersectionObserver
observer = new IntersectionObserver(function(entries, self) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var img = entry.target;
2026-02-02 20:38:58 +08:00
2026-02-03 13:06:58 +08:00
// Load immediately without queue
loadImage(img);
2026-02-02 20:38:58 +08:00
// Stop observing this image once it's triggered
2026-01-31 21:27:06 +08:00
self.unobserve(img);
}
});
}, {
2026-02-02 20:38:58 +08:00
rootMargin: "0px 0px " + defaults.offsetBottom + "px 0px",
threshold: 0.01
2026-01-31 21:27:06 +08:00
});
2026-02-02 20:38:58 +08:00
observeImages();
2026-01-31 19:24:22 +08:00
}
2026-02-03 13:06:58 +08:00
// Removed addToQueue and processQueue functions as we want instant loading
2026-02-02 20:38:58 +08:00
function observeImages() {
var images = document.querySelectorAll('img.lazyload, .post-content img:not(.lazy-loaded)');
2026-01-31 19:24:22 +08:00
images.forEach(function(img) {
2026-02-02 20:38:58 +08:00
if (img.classList.contains('lazy-loaded')) return;
// Update transition duration based on settings
if (defaults.showTime) {
// We'll set this via inline style or rely on CSS class if it matches default
// But for full control, let's set it
img.style.transitionDuration = (defaults.showTime / 1000) + 's';
}
2026-01-31 19:24:22 +08:00
if (img.getAttribute('data-lazy-src')) {
observer.observe(img);
}
});
}
2026-02-02 20:38:58 +08:00
function loadImage(img, callback) {
var src = img.getAttribute('data-lazy-src');
if (!src) {
if (callback) callback();
return;
}
2026-01-31 19:24:22 +08:00
var temp = new Image();
2026-02-02 20:38:58 +08:00
var onComplete = function() {
2026-01-31 19:24:22 +08:00
// Swap source
2026-02-02 20:38:58 +08:00
img.src = src;
2026-01-31 19:24:22 +08:00
2026-02-02 20:38:58 +08:00
requestAnimationFrame(() => {
requestAnimationFrame(() => {
img.classList.add('lazy-loaded');
img.removeAttribute('data-lazy-src');
// Execute callback immediately after starting animation logic
if (callback) callback();
});
});
2026-01-31 19:24:22 +08:00
};
2026-02-02 20:38:58 +08:00
temp.onload = onComplete;
2026-01-31 19:24:22 +08:00
temp.onerror = function() {
2026-02-02 20:38:58 +08:00
// Fallback
img.src = src;
requestAnimationFrame(() => {
img.classList.add('lazy-loaded');
if (callback) callback();
});
2026-01-31 19:24:22 +08:00
};
2026-02-02 20:38:58 +08:00
2026-01-31 19:24:22 +08:00
temp.src = src;
}
2026-02-02 20:38:58 +08:00
function loadAllImages() {
var images = document.querySelectorAll('img.lazyload');
images.forEach(function(img) {
loadImage(img);
});
2026-01-31 19:24:22 +08:00
}
window.lazyLoadInit = init;
2026-02-02 20:38:58 +08:00
window.lazyLoadRefresh = observeImages;
2026-01-31 19:24:22 +08:00
})();