Intersection Observer v2 menambahkan kemampuan untuk tidak hanya mengamati persimpangan itu sendiri, tetapi juga mendeteksi apakah elemen yang berpotongan terlihat pada saat persimpangan.
Intersection Observer v1 adalah salah satu API yang mungkin disukai secara universal, dan, sekarang karena
Safari juga mendukungnya,
API ini akhirnya juga dapat digunakan secara universal di semua browser utama. Untuk mengulang materi API dengan cepat,
sebaiknya tonton Supercharged Microtip
Surma tentang Intersection
Observer v1 yang disematkan di bawah.
Anda juga dapat membaca artikel mendalam Surma.
Orang-orang telah menggunakan Intersection Observer v1 untuk berbagai kasus penggunaan seperti
pemuatan lambat gambar dan video,
mendapatkan notifikasi saat elemen mencapai position: sticky
,
mengaktifkan peristiwa analisis,
dan banyak lagi.
Untuk detail selengkapnya, lihat dokumen Intersection Observer di MDN, tetapi sebagai pengingat singkat, seperti inilah tampilan Intersection Observer v1 API dalam kasus yang paling dasar:
const onIntersection = (entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
console.log(entry);
}
}
};
const observer = new IntersectionObserver(onIntersection);
observer.observe(document.querySelector('#some-target'));
Apa tantangan Intersection Observer v1?
Agar jelas, Intersection Observer v1 sangat bagus, tetapi tidak sempurna. Ada
beberapa kasus ekstrem yang tidak dapat ditangani API. Ayo kita lihat lebih dekat!
Intersection Observer v1 API dapat memberi tahu Anda saat elemen di-scroll ke dalam
area pandang jendela, tetapi tidak memberi tahu Anda apakah elemen tersebut tertutup
oleh konten halaman lain (yaitu, saat elemen dioklusi) atau apakah
tampilan visual elemen telah diubah oleh efek visual seperti transform
, opacity
,
filter
, dll., yang secara efektif dapat membuatnya tidak terlihat.
Untuk elemen dalam dokumen tingkat teratas, informasi ini dapat ditentukan dengan menganalisis
DOM melalui JavaScript, misalnya melalui
DocumentOrShadowRoot.elementFromPoint()
,
lalu mempelajari lebih lanjut.
Sebaliknya, informasi yang sama tidak dapat diperoleh jika elemen yang dimaksud terletak di iframe pihak ketiga.
Mengapa visibilitas sebenarnya sangat penting?
Sayangnya, Internet adalah tempat yang menarik pelaku kejahatan dengan niat yang lebih buruk.
Misalnya, penayang tidak tepercaya yang menayangkan iklan bayar per klik di situs konten mungkin diberi insentif
untuk mengelabui orang agar mengklik iklan mereka guna meningkatkan pembayaran iklan penayang (setidaknya
untuk jangka waktu singkat, hingga jaringan iklan menangkapnya).
Biasanya, iklan tersebut ditayangkan dalam iframe.
Sekarang, jika penayang ingin pengguna mengklik iklan tersebut, mereka dapat membuat iframe iklan
sepenuhnya transparan dengan menerapkan aturan CSS iframe { opacity: 0; }
dan menempatkan iframe
di atas sesuatu yang menarik, seperti video kucing lucu yang benar-benar ingin diklik pengguna.
Hal ini disebut clickjacking.
Anda dapat melihat cara kerja serangan clickjacking seperti itu di bagian atas
demo ini (coba "tonton" video kucing
dan aktifkan "mode trik").
Anda akan melihat bahwa iklan di iframe "berpikir" bahwa iklan tersebut menerima klik yang sah, meskipun iklan tersebut
benar-benar transparan saat Anda (pura-pura tidak sengaja) mengkliknya.
Bagaimana cara Intersection Observer v2 memperbaikinya?
Intersection Observer v2 memperkenalkan konsep pelacakan "visibilitas" sebenarnya dari elemen
target seperti yang akan ditentukan oleh manusia.
Dengan menetapkan opsi di
konstruktor IntersectionObserver
,
instance
IntersectionObserverEntry
yang berpotongan akan berisi kolom boolean baru bernama isVisible
.
Nilai true
untuk isVisible
adalah jaminan kuat dari implementasi yang mendasarinya
bahwa elemen target sepenuhnya tidak terhalang oleh konten lain
dan tidak memiliki efek visual yang diterapkan yang akan mengubah atau mendistorsi tampilannya di layar.
Sebaliknya, nilai false
berarti implementasi tidak dapat memberikan jaminan tersebut.
Detail penting dari
spesifikasi
adalah bahwa penerapan diizinkan untuk melaporkan negatif palsu (yaitu, menetapkan isVisible
ke false
meskipun elemen target benar-benar terlihat dan tidak diubah).
Untuk performa atau alasan lainnya, browser membatasi diri untuk bekerja dengan kotak
batas dan geometri garis lurus; browser tidak mencoba mencapai hasil yang sempurna untuk
modifikasi seperti border-radius
.
Meskipun demikian, positif palsu tidak diizinkan dalam keadaan apa pun (yaitu, menetapkan
isVisible
ke true
saat elemen target tidak sepenuhnya terlihat dan tidak diubah).
Seperti apa kode baru dalam praktiknya?
Konstruktor IntersectionObserver
kini menggunakan dua properti konfigurasi tambahan: delay
dan trackVisibility
.
delay
adalah angka yang menunjukkan penundaan minimum dalam milidetik antara notifikasi dari pengamat untuk target tertentu.
trackVisibility
adalah boolean yang menunjukkan apakah observer akan melacak perubahan visibilitas
target.
Penting untuk diperhatikan di sini bahwa jika trackVisibility
adalah true
, delay
harus
setidaknya 100
(yaitu, tidak lebih dari satu notifikasi setiap 100 md).
Seperti yang telah disebutkan sebelumnya, visibilitas mahal untuk dihitung, dan persyaratan ini adalah tindakan pencegahan terhadap
degradasi performa dan konsumsi baterai. Developer yang bertanggung jawab akan menggunakan
nilai terbesar yang dapat ditoleransi untuk penundaan.
Menurut spesifikasi saat ini, visibilitas dihitung sebagai berikut:
Jika atribut
trackVisibility
pengamat adalahfalse
, target dianggap terlihat. Hal ini sesuai dengan perilaku v1 saat ini.Jika target memiliki matriks transformasi yang efektif selain terjemahan 2D atau penskalaan 2D proporsional, target akan dianggap tidak terlihat.
Jika target, atau elemen apa pun dalam rantai blok yang berisinya, memiliki opasitas efektif selain 1,0, target tersebut dianggap tidak terlihat.
Jika target, atau elemen apa pun dalam blockchain yang berisinya, memiliki filter yang diterapkan, target tersebut dianggap tidak terlihat.
Jika implementasi tersebut tidak dapat menjamin bahwa target benar-benar tidak terhalang oleh konten halaman lainnya, target tersebut akan dianggap tidak terlihat.
Artinya, implementasi saat ini cukup konservatif dalam menjamin visibilitas.
Misalnya, menerapkan filter hitam putih yang hampir tidak terlihat seperti filter: grayscale(0.01%)
atau menyetel transparansi yang hampir tidak terlihat dengan opacity: 0.99
akan membuat elemen
tidak terlihat.
Di bawah ini adalah contoh kode singkat yang mengilustrasikan fitur API baru. Anda dapat melihat logika pelacakan kliknya beroperasi di bagian kedua demo (tetapi sekarang, coba "tonton" video anjing). Pastikan untuk mengaktifkan "mode trik" lagi untuk segera mengubah diri Anda menjadi penayang yang tidak jujur dan melihat cara Intersection Observer v2 mencegah klik iklan yang tidak sah dilacak. Kali ini, Intersection Observer v2 kembali hadir! 🎉
<!DOCTYPE html>
<!-- This is the ad running in the iframe -->
<button id="callToActionButton">Buy now!</button>
// This is code running in the iframe.
// The iframe must be visible for at least 800ms prior to an input event
// for the input event to be considered valid.
const minimumVisibleDuration = 800;
// Keep track of when the button transitioned to a visible state.
let visibleSince = 0;
const button = document.querySelector('#callToActionButton');
button.addEventListener('click', (event) => {
if ((visibleSince > 0) &&
(performance.now() - visibleSince >= minimumVisibleDuration)) {
trackAdClick();
} else {
rejectAdClick();
}
});
const observer = new IntersectionObserver((changes) => {
for (const change of changes) {
// ⚠️ Feature detection
if (typeof change.isVisible === 'undefined') {
// The browser doesn't support Intersection Observer v2, falling back to v1 behavior.
change.isVisible = true;
}
if (change.isIntersecting && change.isVisible) {
visibleSince = change.time;
} else {
visibleSince = 0;
}
}
}, {
threshold: [1.0],
// 🆕 Track the actual visibility of the element
trackVisibility: true,
// 🆕 Set a minimum delay between notifications
delay: 100
}));
// Require that the entire iframe be visible.
observer.observe(document.querySelector('#ad'));
Link Terkait
- Draf Editor Terbaru dari spesifikasi Intersection Observer.
- Intersection Observer v2 di Status Platform Chrome.
- Bug Chromium Intersection Observer v2.
- Blink Intent to Implement posting.
Ucapan terima kasih
Terima kasih kepada Simeon Vincent, Yoav Weiss, dan Mathias Bynens yang telah meninjau artikel ini, serta Stefan Zager yang juga telah meninjau dan menerapkan fitur tersebut di Chrome. Gambar hero oleh Sergey Semin di Unsplash.