В Angular можно работать с viewport при помощи директивы IntersectionObserver
, которая позволяет отслеживать, когда элемент становится видимым внутри viewport.
Для начала создадим директиву, которая будет отслеживать элементы, когда они появляются в viewport:
import { Directive, ElementRef, Output, EventEmitter, OnInit, OnDestroy } from '@angular/core'; @Directive({ selector: '[appViewport]' }) export class ViewportDirective implements OnInit, OnDestroy { private observer: IntersectionObserver; @Output() public onViewportEnter = new EventEmitter(); constructor(private elementRef: ElementRef) {} ngOnInit() { const options = { root: null, // используем viewport в качестве root элемента rootMargin: '0px', threshold: 0.1 // задаем пороговое значение, при котором элемент считается видимым }; this.observer = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.isIntersecting) { this.onViewportEnter.emit(); // отключаем наблюдение, чтобы избежать ненужных срабатываний this.observer.unobserve(this.elementRef.nativeElement); } }); }, options); this.observer.observe(this.elementRef.nativeElement); } ngOnDestroy() { this.observer.disconnect(); } }
Теперь, чтобы загружать картинку при прокрутке к ней, нам нужно использовать эту директиву на элементе, который должен быть отслеживаем:
<div appViewport (onViewportEnter)="loadImage()"> <!-- Картинка, которую нужно загрузить --> <img src="placeholder.jpg" [src]="imageSrc" alt="Image"> </div>
В компоненте, который содержит картинку, добавим логику загрузки картинки:
import { Component } from '@angular/core'; @Component({ selector: 'app-image', templateUrl: './image.component.html', styleUrls: ['./image.component.css'] }) export class ImageComponent { public imageSrc: string; public loadImage() { // Загружаем картинку this.imageSrc = 'image.jpg'; } }
Теперь, когда элемент с директивой appViewport
появится внутри viewport, сработает событие onViewportEnter
, которое вызовет метод loadImage()
в компоненте ImageComponent
, и картинка загрузится.