IntersectionObserver'lar, gözlemlenen bir öğenin tarayıcı görüntü alanına ne zaman girip çıktığı konusunda sizi bilgilendirir.
DOM'unuzdaki bir öğenin görünür görüntü alanına ne zaman girdiğini izlemek istediğinizi varsayalım. Bunu, resimleri tam zamanında yüklemek veya kullanıcının gerçekten belirli bir reklam banner'ına bakıp bakmadığını öğrenmek için yapabilirsiniz. Bunu, kaydırma etkinliğini bağlayarak veya periyodik bir zamanlayıcı kullanarak ve söz konusu öğede getBoundingClientRect()
işlevini çağırarak yapabilirsiniz.
Ancak getBoundingClientRect()
çağrısı her yapıldığında tarayıcıyı sayfanın tamamını yeniden biçimlendirmeye 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 sorun, örneğin sık sık iframe'ler kullanılarak yüklenen reklamlarda yaygındır.
IntersectionObserver
, bu görünürlük testini daha verimli hale getirmek için tasarlandı ve tüm modern tarayıcılarda kullanıma sunuldu. 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.

IntersectionObserver
oluşturma
API oldukça küçüktür ve en iyi şekilde bir örnekle 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 çok 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 gönderilir. 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
, öğenin ne kadarının görünür olduğunu belirtir. Bu bilgilerden yararlanarak öğeleri ekranda görünmeden önce tam zamanında yükleme gibi özellikleri uygulayabilirsiniz. Verimli bir şekilde.

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 arama ç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ırmalı 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ünüz 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 verileri 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. Sentinel'i doğru şekilde geri dönüştürürseniz observe()
'e ek çağrı yapılması gerekmez. IntersectionObserver
çalışmaya devam eder.

Daha fazla güncelleme
Daha önce de belirtildiği gibi, geri çağırma işlevi, gözlemlenen öğe kısmen görünüme 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şikleri dizisi tanımlamanıza olanak tanır. intersectionRatio
bu değerlerden birini her geçtiğinde geri arama 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ştirirseniz öğenin dörtte biri görünür hale geldiğinde her seferinde bildirim alırız:

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"
biçiminde 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 nedir?
IntersectionObserver
'ün kasıtlı olarak piksel mükemmelliği veya düşük gecikmesi olmadığını unutmayın. Bu verileri, kaydırma işlemine bağlı animasyonlar gibi işlemleri uygulamak için kullanmak başarısız olacaktır. Çünkü veriler, kullanacağı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ı sayfada bulabilirsiniz.
Geri aramada ne kadar iş 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 deneyim sunar. Gerekirse eski tarayıcılarda polyfill kullanılabilir. WICG'nin deposunda polyfill'e ulaşabilirsiniz. Bu polyfill'i kullanarak yerel uygulamanın size sunacağı performans avantajlarından yararlanamayacağınız açıktır.
IntersectionObserver
'ü hemen kullanmaya başlayabilirsiniz. Ne gibi bir çözüm ürettiğinizi bize bildirin.