Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 1x | <template> <div v-if="!loaded" class="lazy-placeholder" data-testid="lazy-placeholder" aria-hidden="true" /> <img :id="id" loading="lazy" :src="./error || !src ? defaultLogo : src" :alt="alt" ref="imgRef" :class="clsx('img-fluid', className ?? '', { lazyloaded: loaded, lazyloading: !loaded })" @load="onLoad" @error="onError" @click="onClick" /> </template> <script setup lang="ts"> import { clsx } from 'clsx'; import { onMounted, onUnmounted, ref } from 'vue'; defineProps<{ id?: string; className?: string; src?: string | null; alt?: string; onClick?: () => void; }>(); const defaultLogo = 'https://upload.wikimedia.org/wikipedia/commons/a/ac/No_image_available.svg'; const loaded = ref(false); const error = ref(false); const imgRef = ref<HTMLImageElement | null>(null); function onLoad() { loaded.value = true; } function onError() { error.value = true; } onMounted(() => { const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { observer.disconnect(); } }, { threshold: 0.1 } ); if (imgRef.value) observer.observe(imgRef.value); onUnmounted(() => observer.disconnect()); }); </script> <style scoped src="././LazyImage.scss" /> |