IntersectionObserver's geliyor

IntersectionObserver'lar, gözlemlenen bir öğenin tarayıcı görüntü alanına ne zaman girip çıktığı konusunda sizi bilgilendirir.

Tarayıcı Desteği

  • Chrome: 51.
  • Edge: 15.
  • Firefox: 55.
  • Safari: 12.1

Kaynak

DOM'unuzdaki bir öğenin görünür görüntü alanına ne zaman girdiğini izlemek istediğinizi varsayalım. Resimleri tam zamanında yüklemek için veya kullanıcının gerçekten belirli bir reklam banner'ına bakıp bakmadığını öğrenmek için bunu yapabilirsiniz. Bu işlemi, kaydırma etkinliğini bağlayarak veya periyodik bir zamanlayıcı kullanıp bu öğe için getBoundingClientRect() çağrısı yaparak gerçekleştirebilirsiniz.

Ancak bu yaklaşım, getBoundingClientRect() işlevine yapılan her çağrı tarayıcıyı sayfanın tamamını yeniden düzenlemeye zorladığı ve web sitenizde ciddi olumsuzluklara neden olduğu için çok yavaştır. Sitenizin bir iframe içine yüklendiğini biliyorsanız ve kullanıcının bir öğeyi ne zaman görebileceğini bilmek istediğinizde konular imkânsıza yaklaşır. Tek Kaynak Modeli ve tarayıcı, iframe'i içeren web sayfasındaki verilere erişmenize izin vermez. Bu durum, örneğin sık sık iframe'ler kullanılarak yüklenen reklamlarda yaygın bir sorundur.

IntersectionObserver, için tasarlanmış olan bu görünürlük testini daha verimli hale getirdi ve tüm modern tarayıcılarda kullanılabilir. IntersectionObserver, gözlemlenen bir öğenin tarayıcı görüntü alanına ne zaman girdiğini veya görüntü alanından ne zaman çıktığını size bildirir.

Iframe görünürlüğü

IntersectionObserver nasıl oluşturulur?

API oldukça küçüktür ve en iyi şekilde bir örnek kullanılarak açıklanabilir:

const io = new IntersectionObserver(entries => {
  console.log(entries);
}, {
  /* Using default options. Details below */
});

// Start observing an element
io.observe(element);

// Stop observing an element
// io.unobserve(element);

// Disable entire IntersectionObserver
// io.disconnect();

IntersectionObserver için varsayılan seçenekler kullanıldığında geri çağırma işleviniz hem öğe kısmen görüntüye girdiğinde hem de görüntü alanından tamamen çıktığında çağrılır.

Birden fazla öğeyi gözlemlemeniz gerekiyorsa observe()'ı birden fazla kez çağırarak aynı IntersectionObserver örneğini kullanarak birden fazla öğeyi gözlemlemeniz hem mümkündür hem de önerilir.

Geri çağırma işlevinize entries parametresi iletilir. Bu parametre, IntersectionObserverEntry nesnelerinden oluşan bir dizidir. Bu tür nesnelerin her biri, gözlemlenen öğelerinizden biri için güncellenmiş kesişim verilerini içerir.

🔽[IntersectionObserverEntry]
    time: 3893.92
    🔽rootBounds: ClientRect
        bottom: 920
        height: 1024
        left: 0
        right: 1024
        top: 0
        width: 920
    🔽boundingClientRect: ClientRect
    // ...
    🔽intersectionRect: ClientRect
    // ...
    intersectionRatio: 0.54
    🔽target: div#observee
    // ...

rootBounds, varsayılan olarak görüntü alanı olan kök öğede getBoundingClientRect() çağrılmasının sonucudur. boundingClientRect, gözlemlenen öğede çağrılan getBoundingClientRect() işlevinin sonucudur. intersectionRect, bu iki dikdörtgenin kesişimidir ve gözlemlenen öğenin hangi kısmının göründüğünü etkili bir şekilde belirtir. intersectionRatio yakından ilişkilidir ve öğenin ne kadarının göründüğünü belirtir. Bu bilgiler sayesinde artık öğeleri ekranda görünmeden önce tam zamanında yükleme gibi özellikleri kullanabilirsiniz. Verimli bir şekilde.

Kesişim oranı.

IntersectionObserver'ler verilerini eşzamansız olarak yayınlar ve geri çağırma kodunuz ana iş parçacığında çalışır. Ayrıca, spesifikasyonda IntersectionObserver uygulamalarının requestIdleCallback() kullanması gerektiği belirtiliyor. Bu, sağladığınız geri çağırma çağrısının düşük öncelikli olduğu ve boş zamanlarında tarayıcı tarafından yapılacağı anlamına gelir. Bu, bilinçli bir tasarım kararıdır.

Kayan div'ler

Bir öğenin içinde kaydırma yapmayı pek sevmem ancak sizi yargılamak için burada değilim, IntersectionObserver de değil. options nesnesi, kök olarak görüntü alanının alternatifini tanımlamanıza olanak tanıyan bir root seçeneği alır. root öğesinin, gözlemlenen tüm öğelerin atası olması gerektiğini unutmayın.

Her şeyi kesiştirin.

Hayır Kötü geliştirici! Bu, kullanıcınızın CPU döngüleri dikkatli bir şekilde kullanılmaz. Örnek olarak sonsuz kaydırma çubuğunu düşünelim: Bu senaryoda, DOM'a sentinel eklemek ve bunları gözlemlemek (ve geri dönüştürmek) kesinlikle önerilir. Sonsuz kaydırma çubuğunun son öğesine yakın bir gözetleyici eklemeniz gerekir. Bu gözcü görünür hale geldiğinde, verileri yüklemek, sonraki öğeleri oluşturmak, bunları DOM'a eklemek ve gözcüyü uygun şekilde yeniden konumlandırmak için geri çağırma işlevini kullanabilirsiniz. Gözetleyiciyi uygun şekilde geri dönüştürürseniz observe() çağrısı gerekmez. IntersectionObserver çalışmaya devam eder.

Sonsuz kaydırma çubuğu

Lütfen daha fazla güncelleme

Daha önce de belirtildiği gibi, geri çağırma işlevi, gözlemlenen öğe kısmen görüntüye girdiğinde bir kez ve görüntü alanından çıktığında bir kez tetiklenir. Bu sayede IntersectionObserver, "X öğesi görünür mü?" sorusuna yanıt verir. Ancak bazı kullanım alanlarında bu yeterli olmayabilir.

Bu noktada threshold seçeneği devreye girer. intersectionRatio eşiği dizisi tanımlamanıza olanak tanır. intersectionRatio bu değerlerden birini her geçtiğinde geri çağırma işleviniz çağrılır. threshold için varsayılan değer, varsayılan davranışı açıklayan [0] değeridir. threshold değerini [0, 0.25, 0.5, 0.75, 1] olarak değiştirirsek öğenin dörtte biri daha görünür olduğunda bildirim alırız:

Eşik animasyonu.

Başka seçenek var mı?

Şu an için, yukarıda listelenenlere ek olarak yalnızca bir seçenek vardır. rootMargin, kök için kenar boşluklarını belirtmenize olanak tanır ve böylece kesişimler için kullanılan alanı büyütmenizi veya daraltmanızı sağlar. Bu kenar boşlukları, sırasıyla üst, sağ, alt ve sol kenar boşluğunu belirten "10px 20px 30px 40px" gibi bir CSS stili dizesi kullanılarak belirtilir. Özetlemek gerekirse IntersectionObserver seçenek yapısı aşağıdaki seçenekleri sunar:

new IntersectionObserver(entries => {/* … */}, {
  // The root to use for intersection.
  // If not provided, use the top-level document's viewport.
  root: null,
  // Same as margin, can be 1, 2, 3 or 4 components, possibly negative lengths.
  // If an explicit root element is specified, components may be percentages of the
  // root element size.  If no explicit root element is specified, using a
  // percentage is an error.
  rootMargin: "0px",
  // Threshold(s) at which to trigger callback, specified as a ratio, or list of
  // ratios, of (visible area / total area) of the observed element (hence all
  // entries must be in the range [0, 1]).  Callback will be invoked when the
  // visible ratio of the observed element crosses a threshold in the list.
  threshold: [0],
});

<iframe> sihir

IntersectionObserver'ler, özellikle reklam hizmetleri ve sosyal ağ widget'ları göz önünde bulundurularak tasarlanmıştır. Bu widget'lar sıklıkla <iframe> öğelerini kullanır ve görüntülenip görüntülenmediğini bilmekten yararlanabilir. Bir <iframe>, öğelerinden birini gözlemlerse hem <iframe>'nin hem de <iframe>'yi içeren pencerenin kaydırması geri çağırma işlevini uygun zamanlarda tetikler. Ancak ikinci durumda, kaynaklar arasında veri sızıntısı olmaması için rootBounds, null olarak ayarlanır.

IntersectionObserver Not neyle ilgili?

IntersectionObserver'ün kasıtlı olarak piksel mükemmelliği veya düşük gecikmesi olmadığını unutmayın. Veriler, kesinlikle kullanacağınız zamana kadar güncelliğini yitireceği için kaydırmaya dayalı animasyonlar gibi çabaları uygulamak üzere bunların kullanılması kesinlikle başarısız olur. Açıklayıcı bölümünde, IntersectionObserver ürününün orijinal kullanım alanları hakkında daha ayrıntılı bilgi bulabilirsiniz.

Geri arama kapsamında ne kadar işlem yapabilirim?

Kısa ve öz: Geri arama için çok fazla zaman harcamak uygulamanızın gecikmesine neden olur. Yaygın uygulamaların hepsi geçerlidir.

Öğelerinizi kesiştirin

IntersectionObserver, tüm modern tarayıcılarda kullanılabildiğinden tarayıcı desteği açısından iyi bir seçenektir. Gerekirse eski tarayıcılarda polyfill kullanılabilir. WICG'nin deposunda polyfill'e ulaşabilirsiniz. Bu polyfill'i kullanarak doğal bir uygulamanın size sunacağı performans avantajlarından yararlanamazsınız.

IntersectionObserver'ü hemen kullanmaya başlayabilirsiniz. Ne tür bir çözüm önerdiğinizi bize bildirin.