IntersectionObserver's geliyor

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

Tarayıcı Desteği

  • 51
  • 15
  • 55
  • 12.1

Kaynak

DOM'unuzdaki bir öğenin görünür görüntü alanına girdiğinde bunu izlemek istediğinizi varsayalım. Bu yöntemi, resimleri tam zamanında yüklemek için veya kullanıcının belirli bir reklam banner'ına gerçekten baktığını bilmeniz gerektiği için isteyebilirsiniz. Bunu kaydırma etkinliğini bağlayarak veya periyodik bir zamanlayıcı kullanarak söz konusu öğede getBoundingClientRect() çağırarak yapabilirsiniz.

Ancak bu yaklaşım oldukça yavaştır, çünkü getBoundingClientRect() öğesine yapılan her çağrı, tarayıcıyı tüm sayfayı yeniden düzenlemeye zorlar ve web sitenizde önemli ölçüde olumsuzluk yaratır. Sitenizin bir iframe içinde yüklendiğini bildiğiniz ve kullanıcının bir öğeyi ne zaman görebildiğini bilmek istediğiniz durumlarda işler imkansız hale gelir. Tek Kaynak Model ve tarayıcı, iframe'i içeren web sayfasından hiçbir veriye erişmenize izin vermez. Bu, örneğin sıklıkla iframe'ler kullanılarak yüklenen reklamlarda yaygın olarak görülen bir sorundur.

IntersectionObserver tasarımlarının sonucunda bu görünürlük testini daha verimli hale getirmek için tasarlanmıştır ve tüm modern tarayıcılara geliştirilmiştir. 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 oluşturma

API oldukça küçüktür ve en iyi açıklamasını bir örnek üzerinden yaparız:

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 kısmen görünüme girdiğinde ve görüntü alanından tamamen çıktığında geri çağırmanız çağrılır.

Birden çok öğeyi gözlemlemeniz gerekiyorsa observe() yöntemini birden çok kez çağırarak aynı IntersectionObserver örneğini kullanan birden fazla öğeyi gözlemlemeniz de önerilir.

IntersectionObserverEntry nesne dizisi olan geri çağırmanıza bir entries parametresi aktarılır. 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ı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 bölümünün görünür olduğunu etkili bir şekilde size bildirir. intersectionRatio yakından ilişkilidir ve öğenin ne kadarının görünür olduğunu belirtir. Elinizdeki bu bilgiler sayesinde artık öğeleri ekranda görünür olmadan önce tam zamanında yükleme gibi özellikleri uygulayabilirsiniz. Verimli bir şekilde.

Kesişme oranı.

IntersectionObserver öğeleri verilerini eşzamansız olarak yayınlar ve geri çağırma kodunuz ana ileti dizisinde çalışır. Ayrıca spesifikasyonda, IntersectionObserver uygulamalarında requestIdleCallback() kullanılması gerektiği belirtilmektedir. Bu, sağladığınız geri çağırma çağrısının düşük öncelikli olduğu ve boşta kaldığı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ırmaya pek razı değilim, ancak yargıda bulunmam ve IntersectionObserver istemem. options nesnesi, kökünüz 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ırıcıyı örnek olarak düşünelim: Bu senaryoda, DOM'ye koruyucu öğelerin eklenmesi ve bunların gözlemlenmesi (ve geri dönüştürülmesi!) kesinlikle önerilir. Sonsuz kaydırma aracındaki son öğeye yakın bir koruyucu eklemelisiniz. Bu koruyucu görüntülendiğinde, verileri yüklemek, sonraki öğeleri oluşturmak, bunları DOM'ye eklemek ve koruyucuyu uygun şekilde yeniden konumlandırmak için geri çağırmayı kullanabilirsiniz. Koruyucuyu uygun şekilde geri dönüştürürseniz observe() numaralı telefonu kullanmanız gerekmez. IntersectionObserver çalışmaya devam eder.

Sonsuz kaydırıcı

Lütfen daha fazla güncelleme

Daha önce de belirtildiği gibi geri çağırma, gözlemlenen öğe bir kez kısmen görünüme geçtiğinde ve öğe 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 vermiş olursunuz. Ancak bazı durumlarda bu yeterli olmayabilir.

Bu noktada threshold seçeneği devreye girer. Bir intersectionRatio eşiği 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, varsayılan davranışı açıklayan [0] değeridir. threshold değerini [0, 0.25, 0.5, 0.75, 1] olarak değiştirirsek öğenin ek bir dörtte birlik kısmı görünür olduğunda bildirim alırsınız:

Eşik animasyonu.

Başka seçenek var mı?

Şimdilik, yukarıda listelenenlere ek olarak yalnızca bir seçenek mevcuttur. rootMargin, kök için kenar boşluklarını belirtmenize olanak tanır. Bu sayede, 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çenekler struct şu 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'ler, özel olarak reklam hizmetleri ve sosyal ağ widget'ları göz önünde bulundurularak tasarlandı. Bu öğeler, genellikle <iframe> öğelerini kullanıyor ve görünümde olup olmadıklarını bilmek yararlı olabilir. <iframe> öğesi öğ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ı olmaması için null olarak ayarlanır.

IntersectionObserver ne hakkında değil?

IntersectionObserver özelliğinin kasıtlı olarak piksel mükemmelliği ya da düşük gecikme süresi olmadığını unutmayın. Kaydırmaya dayalı animasyonlar gibi işleri uygulamak için bu biçimleri kullanmak, kesinlikle başarısız olacaktır. Çünkü veriler, açıkça ifade edilecek şekilde, kullanacağınız zaman güncelliğini yitirmiş olacaktır. Açıklayıcı, IntersectionObserver için orijinal kullanım alanları hakkında daha fazla ayrıntı içerir.

Geri aramada ne kadar iş yapabilirim?

Short 'n Sweet: Geri çağırma için çok fazla zaman harcamak uygulamanızın gecikmesine neden olur. Yaygın tüm uygulamalar için geçerlidir.

İleri gidin 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 çoklu dolgu kullanılabilir ve WICG'nin deposunda mevcuttur. Elbette, yerel bir uygulamanın size sağlayacağı bu çoklu dolguyu kullanarak performans avantajlarından yararlanamazsınız.

IntersectionObserver uygulamasını hemen kullanmaya başlayabilirsiniz. Aklınızdakini söyleyin.