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. Resimleri tam zamanında yüklemek için veya kullanıcının gerçekten belirli bir reklam banner'ına bakıp bakmadığını öğrenmek için bunu yapabilirsiniz. Bu işlemi, kaydırma etkinliğini bağlayarak veya periyodik bir zamanlayıcı kullanıp bu öğe için getBoundingClientRect()
çağrısı yaparak gerçekleştirebilirsiniz.
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 ciddi 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. Bu durum, örneğin sık sık iframe'ler kullanılarak yüklenen reklamlarda 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 öğ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
nasıl oluşturulur?
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ş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.
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.
Kayan 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.
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 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 eder.
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.
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, 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:
Başka seçenek 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 "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üntülenip görüntülenmediğini 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. 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 bulabilirsiniz.
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.
Öğ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.