mirror of
https://github.com/SaphireLattice/quest-reader.git
synced 2026-11-12 18:40:36 -07:00
Implement lazy image loading (copied from freefall reader)
This commit is contained in:
7 files changed
+123
-5
No files matched your search
+65
-1
@@ -1,5 +1,9 @@
|
||||
class VisitAnalytics {
|
||||
landmarksObserver: IntersectionObserver;
|
||||
lazyloadObserver: IntersectionObserver;
|
||||
lastWidth: number = 0;
|
||||
resizeTimeout: number | null = null;
|
||||
images: HTMLImageElement[] = [];
|
||||
|
||||
constructor() {
|
||||
window.plausible = window.plausible || function () { (window.plausible.q = window.plausible.q || []).push(arguments); };
|
||||
@@ -20,6 +24,14 @@ class VisitAnalytics {
|
||||
threshold: 1.0
|
||||
}
|
||||
);
|
||||
this.lazyloadObserver = new IntersectionObserver(
|
||||
(entries, observer) => this.handleLazyload(entries, observer),
|
||||
{
|
||||
root: null,
|
||||
rootMargin: "75% 0px 75% 0px",
|
||||
threshold: 0.1
|
||||
}
|
||||
);
|
||||
|
||||
{
|
||||
var all = document.querySelectorAll(".chapter-announce");
|
||||
@@ -27,7 +39,18 @@ class VisitAnalytics {
|
||||
this.landmarksObserver.observe(document.querySelector("footer"));
|
||||
}
|
||||
|
||||
console.log("Intersection observer ready");
|
||||
{
|
||||
var all = document.querySelectorAll(".image-post");
|
||||
all.forEach(elem => {
|
||||
this.lazyloadObserver.observe(elem);
|
||||
this.images.push(elem.querySelector(".post-image > img"));
|
||||
});
|
||||
|
||||
this.resizeTimeout = setTimeout(() => this.resizeDebounced(), 200);
|
||||
window.addEventListener("resize", (event) => this.handleResize(event));
|
||||
}
|
||||
|
||||
console.log("Event handlers and observers ready");
|
||||
}
|
||||
|
||||
handleLandmarks(entries: IntersectionObserverEntry[], observer: IntersectionObserver) {
|
||||
@@ -42,5 +65,46 @@ class VisitAnalytics {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
resizeDebounced() {
|
||||
clearTimeout(this.resizeTimeout);
|
||||
this.resizeTimeout = null;
|
||||
|
||||
const elem = document.querySelector(".post-content");
|
||||
// Note: depends on main.css
|
||||
const elemWidth = Math.floor(elem.clientWidth * 0.95);
|
||||
|
||||
if (elemWidth != this.lastWidth) {
|
||||
this.lastWidth = elemWidth;
|
||||
this.images.forEach(img => {
|
||||
const naturalHeight = +img.getAttribute("data-height");
|
||||
const naturalWidth = +img.getAttribute("data-width");
|
||||
img.height = Math.floor(naturalHeight * Math.min(1, elemWidth / naturalWidth));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
handleResize(event) {
|
||||
if (event && event.type == "resize") {
|
||||
if (this.resizeTimeout != null)
|
||||
clearTimeout(this.resizeTimeout);
|
||||
this.resizeTimeout = setTimeout(() => this.resizeDebounced(), 200);
|
||||
}
|
||||
}
|
||||
|
||||
handleLazyload(entries: IntersectionObserverEntry[], observer: IntersectionObserver) {
|
||||
entries.filter(e => e.isIntersecting).forEach(e => {
|
||||
const imgElem = e.target.querySelector<HTMLImageElement>(`img`);
|
||||
|
||||
imgElem.addEventListener("load", () => {
|
||||
imgElem.classList.add("loaded");
|
||||
});
|
||||
imgElem.src = imgElem.getAttribute("data-src");
|
||||
|
||||
observer.unobserve(e.target);
|
||||
console.log(`Lazyloaded ${ e.target.id ? e.target.id : e.target.tagName }`);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
new VisitAnalytics();
|
||||
Reference in new issue
Block a user