From c45a24066d999a71ac611e6bb68393cfaf067984 Mon Sep 17 00:00:00 2001 From: Christoph Urlacher Date: Mon, 16 Dec 2024 02:27:45 +0100 Subject: [PATCH] Lib: Implement LazyImage component (images will be loaded once visible) --- src/lib/components/LazyImage.svelte | 42 +++++++++++++++++++++++++++++ src/lib/lazyload.ts | 30 +++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 src/lib/components/LazyImage.svelte create mode 100644 src/lib/lazyload.ts diff --git a/src/lib/components/LazyImage.svelte b/src/lib/components/LazyImage.svelte new file mode 100644 index 0000000..6012f1a --- /dev/null +++ b/src/lib/components/LazyImage.svelte @@ -0,0 +1,42 @@ + + +
+ {#if load} + {#await loadImage(src)} + + {:then data} + + {/await} + {/if} +
diff --git a/src/lib/lazyload.ts b/src/lib/lazyload.ts new file mode 100644 index 0000000..4775dfb --- /dev/null +++ b/src/lib/lazyload.ts @@ -0,0 +1,30 @@ +// https://www.alexschnabl.com/blog/articles/lazy-loading-images-and-components-in-svelte-and-sveltekit-using-typescript + +let observer: IntersectionObserver; + +const getObserver = () => { + if (observer) return; + + observer = new IntersectionObserver((entries: IntersectionObserverEntry[]) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + entry.target.dispatchEvent(new CustomEvent("LazyVisible")); + } + }); + }); +}; + +// This is used as an action on lazyloaded elements +export const lazyload = (node: HTMLElement) => { + // The observer determines if the element is visible on screen + getObserver(); + + // If the element is visible, the "LazyVisible" event will be dispatched + observer.observe(node); + + return { + destroy() { + observer.unobserve(node); + }, + }; +};