Intersection Observer v2, kesişimleri gözlemlemenin yanı sıra kesişim sırasında kesişen öğenin görünür olup olmadığını algılama özelliğini de ekler.
Intersection Observer v1, muhtemelen herkes tarafından sevilen API'lerden biridir ve Safari de bu API'yi desteklediğine göre artık tüm büyük tarayıcılarda kullanılabilir. API'yi kısaca tekrar öğrenmek için Surma'nın IntersectionObserver v1 ile ilgili aşağıda yerleştirilmiş Süper Yüklü Mikro İpucu videosunu izlemenizi öneririz.
Surma'nın ayrıntılı makalesini de okuyabilirsiniz.
Kullanıcılar Intersection Observer v1'i resim ve videoların gecikmeli yüklenmesi, öğeler position: sticky
'e ulaştığında bildirim alma, analiz etkinlikleri tetikleme ve daha birçok kullanım alanı için kullanmıştır.
Ayrıntılı bilgi için MDN'deki Intersection Observer dokümanlarına göz atın. Intersection Observer v1 API'sinin en temel durumdaki görünümü aşağıdaki gibidir:
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'));
Intersection Observer v1 ile ilgili zorluk nedir?
Intersection Observer v1'in mükemmel olmadığını belirtmek isteriz. API'nin yetersiz kaldığı bazı uç durumlar vardır. Daha yakından inceleyelim.
Intersection Observer v1 API, bir öğenin pencerenin görüntü alanının içine ne zaman kaydırıldığını size söyleyebilir ancak öğenin başka bir sayfa içeriği tarafından örtülüp örtülmediğini (yani öğenin engellenip engellenmediğini) veya öğenin görsel görüntüsünün transform
, opacity
, filter
gibi görsel efektlerle değiştirilip değiştirilmediğini bildirmez. Bu da öğeyi etkili bir şekilde görünmez hale getirebilir.
Üst düzey belgedeki bir öğe için bu bilgiler, DOM'u JavaScript aracılığıyla (ör. DocumentOrShadowRoot.elementFromPoint()
) analiz ederek ve daha sonra daha ayrıntılı bir inceleme yaparak belirlenebilir.
Buna karşılık, söz konusu öğe üçüncü taraf bir iframe'de bulunuyorsa aynı bilgiler elde edilemez.
Gerçek görünürlük neden bu kadar önemli?
İnternet maalesef kötü niyetli kullanıcıları kendine çeken bir yer.
Örneğin, bir içerik sitesinde tıklama başına ödemeli reklam yayınlayan şüpheli bir yayıncı, reklam ödemesini artırmak için kullanıcıları reklamlarını tıklamaya teşvik edebilir (en azından reklam ağı onları yakalayana kadar kısa bir süre için).
Bu tür reklamlar genellikle iframe'larda yayınlanır.
Yayıncı, kullanıcıların bu tür reklamları tıklamasını istiyorsa bir CSS kuralı iframe { opacity: 0; }
uygulayarak ve reklam iFrame'lerini kullanıcıların gerçekten tıklamak isteyeceği sevimli bir kedi videosu gibi ilgi çekici bir öğenin üzerine yerleştirerek reklam iFrame'lerini tamamen şeffaf hale getirebilir.
Buna tıklama tuzakçılığı denir.
Bu tür bir tıklama tuzakçılığı saldırısını bu demo'nun üst kısmında görebilirsiniz (kedi videosunu "izlemeyi" ve "hileli modu" etkinleştirmeyi deneyin).
Iframe'deki reklamın, siz (istemeden) tıkladığınızda tamamen şeffaf olsa bile geçerli tıklamalar aldığını "düşündüğünü" fark edeceksiniz.
Intersection Observer v2 bu sorunu nasıl düzeltir?
Intersection Observer v2, bir hedef öğenin gerçek "görünürlüğünü" bir insanın tanımlayacağı şekilde izleme kavramını sunar.
IntersectionObserver
kurucusunda bir seçenek ayarlayarak kesişimdeki IntersectionObserverEntry
örnekleri isVisible
adlı yeni bir boole alanı içerir.
isVisible
için true
değeri, temel uygulamanın hedef öğenin diğer içerikler tarafından tamamen engellenmediği ve ekrandaki görüntüsünü değiştirecek veya bozacak görsel efektler uygulanmadığı konusunda güçlü bir garantisidir.
Buna karşılık, false
değeri, uygulamanın bu garantiyi veremeyebileceği anlamına gelir.
Özelliğin önemli bir ayrıntısı, uygulamanın yanlış negatif (yani hedef öğe tamamen görünür ve değiştirilmemiş olsa bile isVisible
değerinin false
olarak ayarlanması) bildirmesine izin verilmesidir.
Tarayıcılar, performans veya başka nedenlerle sınırlayıcı kutular ve doğrusal geometriyle çalışmakla sınırlıdır. border-radius
gibi değişiklikler için piksel mükemmelliğinde sonuçlar elde etmeye çalışmazlar.
Bununla birlikte, hiçbir koşulda yanlış pozitiflere izin verilmez (yani hedef öğe tamamen görünür ve değiştirilmemişken isVisible
değerinin true
olarak ayarlanması).
Yeni kod pratikte nasıl görünüyor?
IntersectionObserver
oluşturucusu artık iki ek yapılandırma özelliğini (delay
ve trackVisibility
) kullanıyor.
delay
, gözlemciden belirli bir hedef için gelen bildirimler arasındaki minimum gecikmeyi milisaniye cinsinden gösteren bir sayıdır.
trackVisibility
, gözlemcinin bir hedefin görünürlüğünde yapılan değişiklikleri izleyip izleyemeyeceğini belirten bir boole değeridir.
trackVisibility
true
olduğunda delay
değerinin en az 100
olması gerektiğini (yani 100 ms'de en fazla bir bildirim) unutmayın.
Daha önce de belirtildiği gibi, görünürlüğün hesaplanması pahalıdır ve bu şart, performans düşüşü ve pil tüketimine karşı bir önlemdir. Sorumlu geliştirici, gecikme için tolere edilebilir en yüksek değeri kullanır.
Mevcut özelliğe göre görünürlük aşağıdaki gibi hesaplanır:
Gözlemcinin
trackVisibility
özelliğifalse
ise hedefin görünür olduğu kabul edilir. Bu, mevcut v1 davranışına karşılık gelir.Hedefin 2D kaydırma veya orantılı 2D yakınlaştırma dışında etkili bir dönüşüm matrisi varsa hedef görünmez olarak kabul edilir.
Hedefin veya içeren blok zincirindeki herhangi bir öğenin etkili opaklığı 1,0'dan farklıysa hedef görünmez olarak kabul edilir.
Hedefe veya içeren blok zincirindeki herhangi bir öğeye filtre uygulanmışsa hedef görünmez olarak kabul edilir.
Uygulama, hedefin diğer sayfa içerikleri tarafından tamamen engellenmediğini garanti edemiyorsa hedef görünmez olarak kabul edilir.
Bu, mevcut uygulamaların görünürlük garantisi konusunda oldukça muhafazakar olduğu anlamına gelir.
Örneğin, filter: grayscale(0.01%)
gibi neredeyse fark edilemeyen bir gri tonlama filtresi uygulamak veya opacity: 0.99
ile neredeyse görünmez bir saydamlık ayarlamak, öğeyi görünmez hale getirir.
Aşağıda, yeni API özelliklerini gösteren kısa bir kod örneği verilmiştir. Tıklama izleme mantığının işleyişini demo'nun ikinci bölümünde görebilirsiniz (ancak şimdilik köpek yavrusu videosunu "izlemeyi" deneyin). Kendinizi hemen şüpheli bir yayıncıya dönüştürmek ve Intersection Observer v2'nin meşru olmayan reklam tıklamalarının izlenmesini nasıl engellediğini görmek için "hileli modu" tekrar etkinleştirdiğinizden emin olun. Bu kez Intersection Observer v2 bize destek oluyor. 🎉
<!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'));
İlgili Bağlantılar
- Intersection Observer spesifikasyonunun en son düzenleyici taslağı.
- Chrome Platform Durumu'nda Intersection Observer v2.
- Intersection Observer v2 Chromium hatası.
- Yayınlama işlemini gerçekleştirme niyeti
Teşekkür ederiz
Bu makaleyi inceleyen Simeon Vincent, Yoav Weiss ve Mathias Bynens ile Chrome'da özelliği inceleyip uygulayan Stefan Zager'e teşekkür ederiz. Unsplash'taki Sergey Semin'in lokomotif resmi.