IntersectionObserver's geliyor

IntersectionObservers, gözlemlenen bir öğe tarayıcının görüntü alanına girdiğinde veya çıktığında bunu size bildirir.

Tarayıcı Desteği

  • 51
  • 15
  • 55
  • 12.1

Kaynak

DOM'nizdeki bir öğe, görünür görünüm alanına girdiğinde bunu izlemek istediğinizi varsayalım. Resimleri zamanında geç yükleyebilmek veya kullanıcının gerçekten belirli bir reklam banner'ına bakıp bakmadığını bilmek için bunu yapmak isteyebilirsiniz. Bu işlemi kaydırma etkinliğini bağlayarak veya periyodik zamanlayıcı kullanarak getBoundingClientRect() numaralı telefonu arayarak yapabilirsiniz. görebilirsiniz.

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 büyük 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. Örneğin, iframe kullanılarak sık yüklenen reklamlar için bu 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 öğe tarayıcının görüntü alanına girdiğinde veya çıktığında bunu size bildirir.

iFrame görünürlüğü

IntersectionObserver nasıl oluşturulur?

API oldukça küçüktür ve en iyi bir örnekle açıklanır:

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ılarak, hem öğe görünüme kısmen geldiğinde hem de görüntü alanından tamamen çıktığında geri çağırmanız yapılır.

Birden fazla öğeyi gözlemlemeniz gerekirse observe() öğesini birden çok kez çağırarak aynı IntersectionObserver örneğini kullanarak birden fazla öğeyi gözlemlemeniz mümkündür.

IntersectionObserverEntry nesneden oluşan bir dizi olan geri çağırmanıza entries parametresi aktarılır. Bu tür her nesne, gözlemlenen öğelerinizden biri için güncellenmiş kesişim verileri 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ü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şme oranı.

IntersectionObserver öğeleri, verilerini eşzamansız olarak gönderir ve geri çağırma kodunuz ana iş parçacığında çalışır. Ayrıca, spesifikasyon aslında IntersectionObserver uygulamalarında requestIdleCallback() kullanılması gerektiğini belirtmektedir. Bu, sağladığınız geri çağırmanın düşük öncelikli olduğu ve boşta kalma zamanı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 gezinmeyi pek sevmem ancak IntersectionObserver gibi bir karar da vermem mümkün değil. options nesnesi, kök olarak görüntü alanına bir alternatif tanımlamanıza olanak tanıyan bir root seçeneği kullanı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üleri dikkatli bir şekilde kullanılmaz. Örnek olarak bir sonsuz kaydırıcıyı düşünelim: Bu senaryoda, DOM'ye koruyucular eklemeniz ve bunları gözlemlemeniz (ve geri dönüştürmeniz!) kesinlikle önerilir. Infinite Scroller'daki son öğenin yakınına bir koruyucu eklemeniz gerekir. Söz konusu koruyucu görünür hale geldiğ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. Sentinel'i uygun şekilde geri dönüştürürseniz ek bir observe() çağrısına gerek yoktur. IntersectionObserver çalışmaya devam eder.

Sonsuz kaydırıcı

Daha fazla güncelleme lütfen

Daha önce de belirtildiği gibi, geri çağırma, gözlemlenen öğe görünüme kısmen geldiğinde ve görüntü alanından çıktığında başka bir zaman tetiklenir. Böylece IntersectionObserver, "X öğesi görüntüleniyor mu?" sorusuna yanıt verir. Ancak bazı kullanım alanlarında bu yeterli olmayabilir.

Bu noktada threshold seçeneği devreye girer. Bir dizi intersectionRatio eşiği tanımlamanıza olanak tanır. intersectionRatio bu değerlerden biriyle her geçtiğinde geri çağırmanız gerekir. 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çenekleriniz 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 CSS stili bir dize (á la "10px 20px 30px 40px") kullanılarak belirlenir. Özetle, IntersectionObserver seçenekleri 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'lar, sıklıkla <iframe> öğelerini kullanan ve görünür olup olmadıklarını öğrenmekten yararlanabilen reklam hizmetleri ve sosyal ağ widget'ları düşünülerek özel olarak tasarlanmıştır. <iframe>, öğelerinden birini gözlemlerse hem <iframe> öğesinin kaydırılması 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 değil neyle ilgili?

IntersectionObserver işlevinin kasıtlı olarak ne piksel mükemmeli ne de düşük gecikme süresi olduğu unutulmamalıdır. 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 verilmiştir.

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.

Elementlerinizle kesişin.

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

IntersectionObserver hizmetini kullanmaya hemen başlayabilirsiniz. Aklınıza gelen her şeyi bizimle paylaşın.