IntersectionObserver's geliyor

IntersectionObservers'lar, gözlemlenen bir öğe tarayıcının görüntü alanına girdiğinde veya buradan çıktığında sizi bilgilendirir.

Tarayıcı Desteği

  • 51
  • 15
  • 55
  • 12.1

Kaynak

DOM'nizdeki bir öğenin görünür görünüm alanına girdiğini izlemek istediğinizi varsayalım. Resimleri tam zamanında yüklemek veya kullanıcının belirli bir reklam banner'ına gerçekten baktığını öğrenmek için bu yöntemi uygulayabilirsiniz. Bu işlemi, kaydırma etkinliğini bağlayarak veya periyodik bir zamanlayıcı kullanarak ve söz konusu öğede getBoundingClientRect() çağrısı yaparak gerçekleştirebilirsiniz.

Ancak bu yaklaşım, getBoundingClientRect() öğesine yapılan her çağrı tarayıcıyı tüm sayfayı yeniden düzenlemeye zorladığı ve web sitenizde önemli ölçüde olumsuz etki yaratacağı için bu yaklaşım oldukça yavaştır. Sitenizin bir iframe içinde yüklendiğini bildiğiniz ve kullanıcının bir öğeyi ne zaman görebileceğini bilmek istiyorsanız önemli konular neredeyse imkansızdır. Tek Kaynaklı Model ve tarayıcı, iframe'i içeren web sayfasından hiçbir veriye erişmenize izin vermez. Bu, örneğin iframe'ler kullanılarak sıklıkla yüklenen reklamlar için yaygın bir sorundur.

IntersectionObserver, bu görünürlük testini daha verimli hale getirmek amacıyla tasarlanmıştır ve tüm modern tarayıcılara sunulmuştur. IntersectionObserver, gözlemlenen bir öğe tarayıcının görüntü alanına girdiğinde veya bu alandan çıktığında sizi bilgilendirir.

iFrame görünürlüğü

IntersectionObserver nasıl oluşturulur?

API oldukça küçüktür ve en iyi açıklaması için aşağıdaki örnekler verilebilir:

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, öğe hem kısmen görünüme girdiğinde hem de görüntü alanından tamamen çıktığında geri çağırma işleminiz çağrılır.

Birden çok öğeyi gözlemlemeniz gerekiyorsa observe() öğesini birden fazla kez çağırarak aynı IntersectionObserver örneğini kullanan birden fazla öğeyi gözlemlemeniz hem mümkündür hem de tavsiye edilir.

IntersectionObserverEntry nesne dizisi olan geri çağırmanıza bir entries parametresi aktarılır. Bu tür her nesne, 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ısı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ünür olduğunu etkili bir şekilde bildirir. intersectionRatio yakından alakalıdır ve öğenin ne kadarının görünür olduğunu belirtir. Elinizin altındaki bu bilgiler sayesinde artık öğeleri ekranda görünmeden önce tam zamanında yükleme gibi özellikleri uygulayabilirsiniz. Hem de verimli bir şekilde.

Kesişme oranı.

IntersectionObserver'ler verilerini eşzamansız olarak yayınlar ve geri çağırma kodunuz ana iş parçacığında çalışır. Buna ek olarak spesifikasyon, IntersectionObserver uygulamalarının requestIdleCallback() kullanması gerektiğini de belirtir. Bu, sağladığınız geri çağırmanın düşük öncelikli olduğu ve boşta kalma süresinde 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ırmayı çok sevmem ama yargılamak için burada değilim ve IntersectionObserver de değil. options nesnesi, kök dizininiz olarak görüntü alanına bir alternatif tanımlamanızı sağlayan bir root seçeneği alır. root öğesinin gözlemlenen tüm öğelerin üst öğesi olması gerektiğini unutmayın.

Her şeyi kesiştirin!

Hayır Kötü geliştirici! Bu, kullanıcınızın CPU döngülerinin bilinçli bir şekilde kullanılması anlamına gelmez. Bir sonsuz kaydırma aracını örnek olarak ele alalım: Bu senaryoda, DOM'ye koruyucuların eklenmesi ve bunların gözlemlenmesi (ve geri dönüştürülmesi) kesinlikle önerilir. Sonsuz kaydırma çubuğundaki son öğeye yakın bir koruyucu eklemeniz gerekir. Bu koruyucu görüntülendiğinde, verileri yüklemek, sonraki öğeleri oluşturmak, bunları DOM'ye eklemek ve gözetleyiciyi uygun şekilde yeniden konumlandırmak için geri çağırma işlevini kullanabilirsiniz. Koruyucuyu uygun şekilde geri dönüştürürseniz observe() numarasına ek bir çağrı yapılmasına gerek yoktur. IntersectionObserver çalışmaya devam eder.

Sonsuz kaydırma çubuğu

Daha fazla güncelleme lütfen

Daha önce belirtildiği gibi, geri çağırma, gözlemlenen öğe kısmen görünüme girdiğinde bir kez ve görüntü alanından ayrıldığında bir kez daha tetiklenir. Bu şekilde IntersectionObserver, "X öğesi görüntüleniyor mu?" sorusuna yanıt vermenizi sağlar. Ancak bazı durumlarda bu yeterli olmayabilir.

Bu noktada threshold seçeneği devreye girer. Bir intersectionRatio eşik dizisi tanımlamanıza olanak tanır. intersectionRatio bu değerlerden birini her aştığında geri çağırmanız çağrılır. threshold için varsayılan değer olan [0], varsayılan davranışı açıklar. threshold değerini [0, 0.25, 0.5, 0.75, 1] olarak değiştirirsek öğenin fazladan dörtte biri görünür olduğunda bildirim alırsınız:

Eşik animasyonu.

Başka seçenek var mı?

Şimdilik yukarıda listelenenler dışında yalnızca bir seçenek bulunmaktadır. rootMargin, kök için kenar boşluklarını belirtmenize olanak tanır. Böylece, kesişimler için kullanılan alanı etkili bir şekilde büyütebilir veya küçültebilirsiniz. Bu kenar boşlukları, sırasıyla üst, sağ, alt ve sol kenar boşluğunu belirten CSS stili bir dize (á la "10px 20px 30px 40px") kullanılarak belirtilir. Özetle, IntersectionObserver seçenekleri struct 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> büyüsü

IntersectionObserver'lar, özel olarak reklam hizmetleri ve sosyal ağ widget'ları göz önünde bulundurularak tasarlanmıştır. Bu özellikler, sıklıkla <iframe> öğelerini kullanır ve görünümde olup olmadıklarını bilmek yararlı olabilir. <iframe>, öğelerinden birini gözlemlerse hem <iframe> hem de <iframe> öğesini içeren pencerenin kaydırılması uygun zamanlarda geri çağırmayı tetikler. Ancak ikinci durumda rootBounds, kaynaklar arasında veri sızıntısını önlemek için null olarak ayarlanır.

IntersectionObserver ne hakkında değil?

Unutulmaması gereken bir nokta, IntersectionObserver özelliğinin kasıtlı olarak ne piksel mükemmeli ne de düşük gecikme süresi olduğudur. Kaydırmaya dayalı animasyonlar gibi işlemlerin uygulanması için bu tür öğelerin kullanılması kesinlikle başarısız olur. Çünkü, kesin şekilde ifade etmek gerekirse veriler, kullanmaya başladığınız zamana kadar güncelliğini yitirmiş olacaktır. IntersectionObserver için orijinal kullanım alanları hakkında daha fazla bilgiyi açıklayıcıda bulabilirsiniz.

Geri aramada ne kadar iş yapabilirim?

Shorts ve Tatlı: Geri çağırma için çok fazla zaman harcamak uygulamanızın gecikmesine neden olur. Tüm yaygın uygulamalar geçerlidir.

Çıkın ve öğelerinizi kesiştirin

Tüm modern tarayıcılarda mevcut olduğundan IntersectionObserver için tarayıcı desteği iyidir. Gerekirse eski tarayıcılarda bir çoklu dolgu kullanılabilir ve WICG'nin deposunda bulunabilir. Elbette, yerel bir uygulamanın size sağlayacağı bu çoklu dolguyu kullandığınızda performans avantajlarından yararlanamazsınız.

IntersectionObserver ürününü kullanmaya hemen başlayabilirsiniz. Karşılaştığınız sorunu bizimle paylaşın.