Intersection Observer API

Problem

Javascript ile istenilen elemanın DOM üzerinde görünüp görünmediğini takip etmek geçmişten beri zor bir işti. Bu işlem için ‘scroll’ eventini dinleyip hedef elemanın DOM üzerindeki konumuna göre aksiyon alıyorduk. Ancak bu yaklaşımda performans sorunları ve istenmeyen davranışlar kaçınılmaz oluyordu. Neyse ki web sitelerinin bu ihtiyaçları geliştikçe bu amaca yönelik bir API geliştirildi.

Deneme Örneğin Element 2 ekranda görünür olduğu anda sitemizin arka planını değiştirmek istiyorsak eskiden izlediğimiz yol şu şekildeydi:

  • Element 2’nin DOM’daki konumunu al.
  • ‘scroll’ eventini izlemeye başla.
  • Scroll konumundan Element 2’nin ekranda görünüp görünmediğini hesapla.
  • Element 2 göründüğünde arka planı değiştir.

Bu yaklaşımda her bir pixellik harekette dahi fonksiyonumuz çalıştığından performans sorunları ile karşılaşabiliriz bunun için optimizasyonlar yapmak zorundayız.

Çözüm

Intersection Observer API kullandığımızda izleyeceğimiz yol şu hale gelir:

  • Element 2’yi Intersection Observer ile izlemeye başla ve callback olarak arka planı değiştirecek bir fonksiyon yaz.
  • Element 2 göründüğünde Intersection Observer arka planı değiştirecektir.

Örnek

Şimdi daha anlaşılır olması için yukarıda resimle gösterdiğimiz senaryoyu koda döküp Intersection Observer API yardımıyla istediğimiz işlemi gerçekleştirmeye çalışalım.

Öncelikle HTML iskeletimizi oluşturalım:

1
2
3
4
<main>
  <div class="element1">ELEMENT 1</div>
  <div class="element2">ELEMENT 2</div>
</main>

Sonrasında elemanlarımızı konumlandırmak ve gerekli arka plan renklerini vermek için css tanımlarımızı ekleyelim;

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
body {
  background: white;
}
main {
  height: 100vh; /* ekranın tamamını kaplaması için bu boyutu verelim */
}
.element1 {
  background: orange;
  height: 100vh;
  text-align: center;
  margin-bottom: 5rem;
}
.element2 {
  background: blue;
  text-align: center;
}

Buraya kadar şu şekilde bir sayfa elde ettik: ObserverOrnek1

Öncelikle Intersection Observer constructor kullanarak bir instance yaratalım ve hedef elemanımızı takip etmeye başlayalım.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Kullanacağımız elemanları tanımlayalım:
const bodyElement = document.querySelector("body");
const element1 = document.querySelector(".element1");
const element2 = document.querySelector(".element2");

// const observer = new IntersectionObserver(callbackFunction,options) (options parametresi özel ayarlar belirtebileceğimiz bir objedir, opsiyoneldir)

// bu callback fonksiyonu observe ettiğimiz elementler ekranda
// gözükmeye başladığında/kaybolduğunda çalışacak
// şimdilik sadece logluyoruz
function callbackFunction(entries) {
  entries.forEach((entry) => {
    console.log(entry);
    alert;
  });
}

// IntersectionObserver instance'ımızı oluşturalım.
const observer = new IntersectionObserver(callbackFunction);

// element2'yi observe etmeye başlayalım:
observer.observe(element2);

Sayfayı tarayıcımızdan açıp element2’ye doğru scroll ettikten sonra console’da şu şekilde bir entry objectinin loglandığını göreceksiniz: ObserverLog Çoğu zaman için en çok işimize yarayacak property’ler intersectionRatio ve isIntersecting olacaktır.

isIntersecting property’si eğer hedef eleman root elemanda (varsayılan olarak viewport kullanılır) gözüküyorsa true gözükmüyorsa false döner.

intersectionRatio ise hedef elemanımızın şu an yüzde kaçının göründüğünü döner. (Örneğin tamamı görünüyorsa 1 , hiç gözükmüyorsa 0.)

Logu inceledikten sonra şimdi hedefimizi gerçekleştirmek için callbackFunction’ımızı yazalım:

1
2
3
4
5
6
7
8
9
function callbackFunction(entries) {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      bodyElement.style.background = "red";
    } else {
      bodyElement.style.background = "white";
    }
  });
}

Artık element2 göründüğünde arka planımızın kırmızı; görünmediğinde ise beyaz olduğunu görebiliriz. Örneği aşağıda inceleyebilirsiniz:

See the Pen Intersection Observer Demo by Furkan (@elbaley) on CodePen.

Options

Intersection Observer constructor’ına ekleyeceğimiz options objecti ile callback fonksiyonumuzun çalışacağı durumlara ince ayar yapabiliriz. Kullanabileceğimiz seçenekler ise şunlar:

root: Elemanımızın direkt olarak sayfada değil, başka bir elemanın içinde görünüp görünmediğini kontrol etmek istediğimizde burada hedef elemanı belirtebiliriz. (Örneğin overflowu gizlenmiş ve kaydırabildiğimiz bir divimiz var bu divi baz alarak görünürlüğü takip etmek istiyorsak bu divi burada belirtebiliriz.) Varsayılan olarak null olduğundan tüm sayfa baz alınır.

rootMargin: CSS’deki margin değeri gibidir. Root nesnemize margin ekleyebiliriz. Bu parametreyi kullanmak için root parametresinin atanmış olması gerekir.

threshold : Hedef elemanımızın yüzde kaçı göründüğünde fonksiyonumuzun çalışacağını belirler. Varsayılan değer 0 olduğundan hedef elemanımızın 1pixeli gözükmeye başladığı anda fonksiyonumuz değisir. Tek bir değer seçebildiğimiz gibi bir array içerisinde birden fazla değer de belirleyebiliriz. (Örneğin 0.5 değerini girersek elemanımızın yarısı gözüktüğü anda fonksiyonumuz çalışır. [0.25,0.5] arrayini atadığımızda ise fonksiyonumuz elemanımızın önce %25i göründüğünde sonra %50’si göründüğünde çalışır. )

Options Demo

İlk demoda mavi arkaplana sahip olan element 2’nin 1 pixeli ekranda görünür görünmez arka plan rengimizi değiştiren fonksiyonumuz çalışıyor. Options objecti oluşturup threshold değerini 1 yaparsak element 2’nin tamamı görünmeyene kadar arka planımız beyaz kalacaktır:

1
2
3
4
const options = {
  threshold: 1,
};
const observer = new IntersectionObserver(callbackFunction, options);

See the Pen Intersection Observer Demo 2 by Furkan (@elbaley) on CodePen.

Referanslar

🔗 MDN Intersection Observer

🔗 Understanding the Intersection Observer JavaScript API

🔗 Intersection Observer’ın nasıl çalıştığını görselleştiren bir pen

comments powered by Disqus
Hugo ile oluşturuldu.
Stack teması Jimmy tarafından tasarlandı