Güvenmek iyidir, gözlem daha iyi: Intersection Observer v2

Kesişim Gözlemcisi v2, kesişimleri tek tek gözlemlemenin yanı sıra aynı zamanda kesişen öğenin kesişim anında görünür olup olmadığını belirler.

Intersection Observer v1, muhtemelen evrensel olarak sevilen API'lerden biridir. Safari de bunu destekler. aynı zamanda da nihayet tüm önemli tarayıcılarda herkesin kullanımına sunuldu. API'yi özetlemek için Surma'nın Kavşak Üzerinde Güçlendirilmiş Mikro Uç Observer v1, aşağıya yerleştirilmiş. Surma'nın bu yıl sonu makalesini inceleyin. İnsanlar Intersection Observer v1'i çok çeşitli kullanım alanları için kullandılar: resimlerin ve videoların geç yüklenmesi, Öğeler position: sticky tutarına ulaştığında bilgilendirilmek, analiz etkinliklerini tetikleme ve çok daha fazlası.

Tüm ayrıntılar için şuraya göz atın: MDN'deki Kesişim Gözlemci belgeleri, ancak kısa bir hatırlatma olarak, Intersection Observer v1 API'nin en çok bu şekilde olduğunu hatırlatmak isteriz. temel durum:

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'de sizi zorlayan noktalar neler?

Açıkça belirtmek gerekirse Intersection Observer v1 mükemmeldir ancak mükemmel değildir. Her biri 100'den az gösterim alan API'nin yetersiz kaldığı bazı yaygın durumlar. Biraz ayrıntılarına inelim. Intersection Observer v1 API'sı, bir öğenin ne zaman pencerenin görüntü alanını görüntülemez, ancak öğenin üzerini kaplayıp kapatmadığını bildirmez. öğe tarafından engellendiğinde veya engellendiğinde öğenin görsel görüntüsü, transform, opacity ve filter gibi, bu tür ekler etkili bir şekilde görünmez hale gelebilir.

Üst düzey belgedeki bir öğe için bu bilgiler analiz edilerek DOM aracılığıyla yükleyebilirsiniz (örneğin, DocumentOrShadowRoot.elementFromPoint() ve daha derinlere ineceğiz. Öte yandan, söz konusu öğe şu şekilde olduğunda aynı bilgiler elde edilemez: üçüncü taraf iframe'de bulunabilir.

Gerçek görünürlük neden bu kadar önemli?

Ne yazık ki İnternet, kötü niyetli kötü niyetli kişileri çeken bir yer. Örneğin, bir içerik sitesinde tıklama başına ödeme reklamları yayınlayan şüpheli bir yayıncı yayıncının reklam ödemesini artırmak (en azından reklam ağı bunları yakalayana kadar kısa bir süre boyunca). Bu tür reklamlar genellikle iframe'ler içinde sunulur. Yayıncı, kullanıcıların bu tür reklamları tıklamalarını sağlamak isterse, reklam iframe'lerini bir CSS kuralı uygulayarak iframe { opacity: 0; } ve iframe'lerin üzerini yerleştirerek tamamen şeffaf gibi bir metin ekleyerek kullanıcıların gerçekten tıklamak isteyecekleri sevimli bir kedi videosu oluşturabilirsiniz. Buna tıklama korsanlığı denir. Bu videonun üst bölümünde, tıklama saldırısının nasıl gerçekleştiğini görebilirsiniz. demo (kedi videosunu "izlemeyi" deneyin "hile modunu" etkinleştirin). iframe'deki reklamın "düşünür" aldığı dönüşüm sırasında istemeden tıkladığınız zaman tamamen şeffaf olur.

Reklamı şeffaf hale getirip ilgi çekici bir şeyin üzerine yerleştirerek kullanıcıyı kandırarak reklamı tıklama.

Intersection Observer v2 bu sorunu nasıl düzeltir?

Kesişim Gözlemcisi v2, gerçek "görünürlüğü" izleme kavramını ortaya koyar hedefin bir insan gibi tanımlar. Şurada bir seçenek belirleyerek IntersectionObserver oluşturucu, kesişen IntersectionObserverEntry örnekleri, bunun ardından isVisible adlı yeni bir boole alanı içerir. isVisible için true değeri, temel uygulamanın güçlü bir garantisidir hedef öğenin başka içerikler tarafından tamamen kapatılmadığından ve ekrandaki görüntüsünü değiştirecek ya da bozacak herhangi bir görsel efekt uygulanmamış olmalıdır. Öte yandan false değeri, uygulamanın bu garantisi veremeyeceği anlamına gelir.

Projenin önemli bir detayı, özellikler uygulamanın yanlış negatifler bildirmesine izin verilmesi (yani isVisible hedef öğe tamamen görünür ve değiştirilmemiş olsa bile false olarak değiştirilir. Performans veya diğer nedenlerden dolayı, tarayıcılar kendilerini sınırlayıcıyla çalışmakla sınırlandırır kutular ve doğrusal geometri; emin olmak için farklı öğeler için border-radius gibi değişiklikler.

Bununla birlikte, yanlış pozitiflere hiçbir koşulda izin verilmez. Hedef öğe tamamen görünür ve değiştirilmemiş olduğunda isVisible değerini true olarak ayarlayın.

Yeni kod pratikte nasıl görünüyor?

IntersectionObserver oluşturucusu artık iki ek yapılandırma özelliği alıyor: delay ve trackVisibility. delay, gelen bildirimler arasındaki minimum gecikmeyi milisaniye cinsinden gösteren bir sayıdır. belirli bir hedef için gözlemcidir. trackVisibility, gözlemcinin bir hedefin görünürlük.

trackVisibility true olduğunda, delay değerinin şu konumda olması gerektiğini unutmayın: en az 100 (yani 100 ms'de en fazla bir bildirim). Daha önce de belirtildiği gibi, görünürlüğün hesaplanması pahalıdır ve bu şart, düşebilir ve pil tüketimini artırabilir. Sorumlu geliştirici, Gecikme için en büyük tolerans edilebilir değeri.

Mevcut tarihe göre spec, görünürlük şu şekilde hesaplanır:

  • Gözlemcinin trackVisibility özelliği false ise hedef görünür olarak kabul edilir. Bu, mevcut v1 davranışına karşılık gelir.

  • Hedefin 2D çeviri dışında etkili bir dönüşüm matrisi varsa söz konusu olduğunda, hedef görünmez olarak kabul edilir.

  • Hedef veya bulunduğu blok zincirindeki herhangi bir öğe 1, 0 ise hedef görünmez olarak kabul edilir.

  • Hedefe veya bulunduğu blok zincirindeki herhangi bir öğeye herhangi bir filtre uygulanmışsa hedef görünmez olarak kabul edilir.

  • Uygulama, hedefin başka bir sayfa tarafından tamamen kapatılacağını garanti edemezse içerik bulunuyorsa hedef görünmez olarak kabul edilir.

Bu, mevcut uygulamaların oldukça ihtiyatlı olduğu ve görünürlük garantisi sağladığı anlamına gelir. Örneğin, filter: grayscale(0.01%) gibi neredeyse fark edilemeyecek bir gri tonlamalı filtre veya opacity: 0.99 ile neredeyse görünmez bir şeffaflık ayarlamak öğenin tamamını oluşturur görünmez.

Aşağıda, yeni API özelliklerini gösteren kısa bir kod örneği verilmiştir. Tıklama izleme özelliğini demonun ikinci bölümündeki mantığın işleyiş şekline (ancak şimdi yavru köpek videosunu "izlemeyi" deneyin). "Hile modu"nu etkinleştirdiğinizden emin olun hemen yerine kendinizi şüpheli bir yayıncıya dönüştürmenizi sağlayacak ve Intersection Observer v2 sürümünün meşru olmayan reklam tıklamalarının izlenmesini engeller. Bu sefer Intersection Observer v2'yi koruyoruz. 🎉

Intersection Observer v2, bir reklamın istenmeden tıklanmasını engelliyor.

<!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'));

Teşekkür

Simeon Vincent sayesinde, Yoav Weiss ve Mathias Bynens bu makaleyi inceleme için ve Stefan Zager'i de aynı şekilde Chrome'daki özelliği incelemek ve uygulamak için kullanın. Sergey Semin'in Unsplash'teki hero resim.