IntersectionObservers, gözlemlenen bir öğe tarayıcının görüntü alanına girdiğinde veya çıktığında bunu size bildirir.
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üğü](https://web.dev/static/articles/intersectionobserver/image/iframe-visibility-45640aaa99537.gif?authuser=0000&hl=tr)
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ı.](https://web.dev/static/articles/intersectionobserver/image/intersection-ratio-cc2e11cc70559.png?authuser=0000&hl=tr)
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ı](https://web.dev/static/articles/intersectionobserver/image/infinite-scroller-f23f2b90aa6bd.png?authuser=0000&hl=tr)
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.](https://web.dev/static/articles/intersectionobserver/image/threshold-animation-818bf785c4e2d.gif?authuser=0000&hl=tr)
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şim yapın
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.