Saat ini dimungkinkan untuk melewati yang dapat diamati yang merupakan cara yang bagus untuk memperluas perpustakaan. Namun, ini agak terbatas karena penggunaannya tidak bisa mendapatkan akses ke gambar dengan cara yang sederhana.
Salah satu masalah paling umum adalah ketika pengguna tidak menggunakan jendela untuk menggulir atau menggunakan pustaka 3 bagian yang menambahkan lapisan gulir tambahan (mis. ionik, desain material ng, dll), dan terkadang sulit ditemukan keluar elemen mana yang benar-benar menggulir. Salah satu cara untuk mengatasi ini adalah dengan menggunakan Intersection Observer
(yang juga dapat memberikan peningkatan kinerja). Misalnya.
@Component({
selector: 'intersection-observer',
template: `<img #img [defaultImage]="defaultImage" [lazyLoad]="image" [scrollObservable]="subject">`,
})
export class IntersectionObserverComponent {
@ViewChild('img') img;
subject = new Subject();
defaultImage = 'https://www.placecage.com/1000/1000';
image = 'https://images.unsplash.com/photo-1467932760935-519284fc87fa?dpr=2&auto=compress,format&fit=crop&w=1199&h=800&q=80';
ngAfterViewInit() {
const config = {
rootMargin: '50px 50px',
threshold: 0.01
};
function onIntersection(entries) {
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
observer.unobserve(entry.target);
this.subject.next();
}
});
}
const observer = new IntersectionObserver(onIntersection, config);
observer.observe(this.img.nativeElement);
}
}
Namun ini cukup rumit.
Apa yang dapat kita lakukan adalah menerima fungsi sebagai scrollObservable
, seperti:
if (!this.scrollObservable) {
const windowTarget = isWindowDefined() ? window : undefined;
scrollObservable = getScrollListener(this.scrollTarget || windowTarget);
} else if (typeof this.scrollObservable === 'function') {
scrollObservable = this.scrollObservable(image, offset) // and maybe more
} else {
scrollObservable = this.scrollObservable.startWith('');
}
Kami tidak dapat menulis ulang komponen di atas menjadi:
@Component({
selector: 'intersection-observer',
template: `<img [defaultImage]="defaultImage" [lazyLoad]="image"
[scrollObservable]="startLazyload" offest="50">`,
})
export class IntersectionObserverComponent {
defaultImage = 'https://www.placecage.com/1000/1000';
image = 'https://images.unsplash.com/photo-1467932760935-519284fc87fa?dpr=2&auto=compress,format&fit=crop&w=1199&h=800&q=80';
startLazyload(image, offset) {
Observable.create(observer => {
const intersectionObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
observer.next();
}
});
}, {
rootMargin: offset ? `${offset}px` : undefined,
threshold: 0.01
});
intersectionObserver.observe(image);
return () => observer.unobserve(image);
});
}
}
Lebih baik tetapi masih sedikit bising, terutama ketika pengguna ingin menggunakan IntersectionObserver
pada semua gambar.
Cara untuk mengatasi ini adalah dengan melewatkan Observable default di NgModule
:
import { intersectionObserverLazyLoad } from 'some-place';
@NgModule({
declarations: [ AppComponent ],
imports: [ BrowserModule, lazyLoadImage({
observable: intersectionObserverLazyLoad
})],
bootstrap: [ AppComponent ]
})
export class MyAppModule {}
Kami tidak dapat menulis ulang komponen di atas menjadi:
@Component({
selector: 'intersection-observer',
template: `<img [defaultImage]="defaultImage" [lazyLoad]="image" offest="50">`,
})
export class IntersectionObserverComponent {
defaultImage = 'https://www.placecage.com/1000/1000';
image = 'https://images.unsplash.com/photo-1467932760935-519284fc87fa?dpr=2&auto=compress,format&fit=crop&w=1199&h=800&q=80';
}
Kemampuan untuk melewatkan fungsi default di NgModule juga dapat membuka pintu untuk membuat fungsi khusus untuk isVisible
dan loadImage
tetapi itu adalah cerita selanjutnya.
Akan memecahkan: #287, #195, #286, #285, #275, #259 dan banyak lagi. Sebagian besar masalah diselesaikan dengan cara lain, tetapi alangkah baiknya jika kami dapat memberi pengguna lebih banyak fleksibilitas saat membuat yang dapat diamati.
Bagaimana menurutmu @sapierens , @rimlin?
@tjoskar seperti yang saya mengerti Anda ingin meningkatkan scrollObservable
dengan menyediakan fungsi sebagai opsi untuk scrollObservable
, yang akan mengembalikan Observable, yang bertanggung jawab untuk memancarkan acara pemuatan gambar? Jika ya, saya pikir itu ide yang sangat keren!
Tapi saya pikir lebih baik menggunakan objek daripada menghitung argumen:
...
} else if (typeof this.scrollObservable === 'function') {
scrollObservable = this.scrollObservable({
image,
offset
});
} else {
...
menyediakan fungsi sebagai opsi untuk scrollObservable, yang akan mengembalikan Observable, yang bertanggung jawab untuk memancarkan acara pemuatan gambar
Benar, saya mungkin juga ingin mengganti nama scrollObservable
tetapi itu akan menjadi perubahan yang melanggar.
saya pikir lebih baik menggunakan objek daripada menghitung argumen
Setuju!
Saya pikir ini adalah ide yang bagus, terutama melewati pengamat default.
saya pikir lebih baik menggunakan objek daripada menghitung argumen
Saya juga setuju dengan ini.
Diperbaiki di #365 dan di versi 2.1.0
Komentar yang paling membantu
@tjoskar seperti yang saya mengerti Anda ingin meningkatkan
scrollObservable
dengan menyediakan fungsi sebagai opsi untukscrollObservable
, yang akan mengembalikan Observable, yang bertanggung jawab untuk memancarkan acara pemuatan gambar? Jika ya, saya pikir itu ide yang sangat keren!Tapi saya pikir lebih baik menggunakan objek daripada menghitung argumen: