export default class LazyLoader { constructor(options = {}) { this.threshold = options.threshold || 0.1; this.rootMargin = options.rootMargin || '50px'; this.observer = null; this.logger = options.logger || null; this._setup(); } _setup() { this.observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { this._loadElement(entry.target); this.observer.unobserve(entry.target); } }); }, { threshold: this.threshold, rootMargin: this.rootMargin } ); } observe(element) { if (!element) return; this.observer.observe(element); } unobserve(element) { if (!element) return; this.observer.unobserve(element); } observeAll(selector) { document.querySelectorAll(selector).forEach((el) => { this.observe(el); }); } _loadElement(element) { try { if (element.dataset.src) { element.src = element.dataset.src; element.removeAttribute('data-src'); this.logger?.debug(`Lazy loaded image: ${element.src}`); } if (element.dataset.backgroundImage) { element.style.backgroundImage = `url(${element.dataset.backgroundImage})`; element.removeAttribute('data-background-image'); this.logger?.debug(`Lazy loaded background image`); } element.classList.add('loaded'); } catch (error) { this.logger?.error('Failed to lazy load element', error); } } destroy() { if (this.observer) { this.observer.disconnect(); } } }