IntersectionObserver's geliyor

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

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 yavaş yüklemek veya kullanıcının gerçekten belirli bir reklam banner'ına bakıp bakmadığını öğrenmek için bunu yapabilirsiniz. Bunu, kaydırma etkinliğini bağlayarak veya periyodik bir zamanlayıcı kullanarak ve ilgili öğede getBoundingClientRect() işlevini çağırarak yapabilirsiniz.

Ancak getBoundingClientRect() çağrısı her yapıldığında tarayıcıyı sayfanın tamamını yeniden düzenlemeye zorladığı ve web sitenizde önemli ölçüde takılmalara neden olduğu için bu yaklaşım son derece 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 istediğiniz durumlarda işler neredeyse imkansız hale gelir. 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, bu görünürlük testini daha verimli hale getirmek için tasarlanmıştır ve tüm modern tarayıcılarda kullanıma sunulmuştur. 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 oluşturma

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şim noktasıdır ve gözlemlenen öğenin hangi kısmının görünür olduğunu etkili bir şekilde gösterir. intersectionRatio ile yakından ilişkili olan bu metrik, öğenin ne kadarının görünür olduğunu gösterir. Bu bilgilerden yararlanarak öğeleri ekranda görünmeden önce tam zamanında yükleme gibi özellikleri uygulayabilirsiniz. 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.

Kaydırılabilir 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.

Tümünü kesişim kümesi olarak alın.

Hayır Kötü geliştirici! Bu, kullanıcınızın CPU döngülerinin bilinçli bir şekilde kullanılması değildir. Ö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 ediyor.

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.

İşte 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 [0] olduğundan varsayılan davranış bu şekildedir. threshold değerini [0, 0.25, 0.5, 0.75, 1] olarak değiştirirsek öğenin dörtte biri görünür hale geldiğinde bildirim alırız:

Eşik animasyonu.

Başka seçenek var mı?

Şu anda yukarıda listelenenlere ek olarak yalnızca bir seçenek daha mevcuttur. 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 "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ünümde olup olmadıklarını 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. Kaydırmaya bağlı animasyonlar gibi girişimleri uygulamak için bu verileri kullanmak, verileri kullanacağınız zamana kadar eski olacağından başarısız olacaktır. IntersectionObserver için orijinal kullanım alanları hakkında daha fazla bilgiyi açıklayıcı makalede bulabilirsiniz.

Geri aramada ne kadar çalışma yapabilirim?

Özet: Geri çağırma işleminde çok fazla zaman harcamak uygulamanızın gecikmesine neden olur. Tüm yaygın uygulamalar 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.