IntersectionObserver'lar, gözlemlenen bir öğenin tarayıcı görüntü alanına ne zaman girip çıktığını size bildirir.
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.
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.
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.
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:
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.