Javascript 30 - Gün 13

6 Mayıs 2023

Javascript ile sayfa kaydırılırken resimlerin gözükmesini sağlayacağız. CSS ile resimler varsayılan olarak opacity değeri sayesinde gizlenmiş ve translate sayesinde bir miktar yerinden oynatılmış halde. Bu resimlere .active sınıfı eklendiğinde geçiş sonrası gözükmeye başlayacaklar.

Projenin demosu : Demo

Başlangıç dosyalarını bulabileceğiniz repom: js-30 | github

Çözümüm

İlk çözümümde resmin ne zaman gösterileceğini hesaplamak için kursta kullanılan önerildiği gibi scroll edilen piksel miktarı ve resmin büyüklüğünü hesapladım. Sonrasında her scroll olayı gerçekleştiğinde resme active sınıfı eklemem gerekiyorsa ekledim silmem gerekiyorsa da sildim.

Bu çözümde bir debounce fonksiyonu kullandım debounce fonksiyonu ile ilgili daha detaylı bilgiyi kodda paylaştım.

<script>
// ============
// 1. VERSIYON 
// ============
// scroll eventini dinlediğimizde 1px bile scroll edildiğinde
// fonksiyon çalışacaktır bunun önüne geçmek için debounce fonksiyonuna ihtiyacımız var
// debounce hakkında detaylı bilgi için : https://bit.ly/3M0fgLq
function debounce(func, wait = 20, immediate = true) {
  let timeout;
  return function () {
    let context = this, args = arguments;
    let later = function () {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };
    let callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
}
 
// önce sayfadaki tüm resimleri seçelim
const sliderImages = document.querySelectorAll(".slide-in")
 
// scroll işlemi yapıldığında bu fonksiyonumuz çağrılır
function checkSlide(e) {
  sliderImages.forEach(sliderImage => {
    // Resmin sayfanın neresinde göründüğünü kontrol etmek için kullanılır
    const slideInAt = (window.scrollY + window.innerHeight) - sliderImage.height / 2
    const imageBottom = sliderImage.offsetTop + sliderImage.height
    // Resmin yarıda gözüküp gözükmediği ve 
    // sayfanın altına kadar kaydırılıp kaydırılmadığını kontrol eder
    const isHalfShown = slideInAt > sliderImage.offsetTop;
    const isNotScrolledPast = window.scrollY < imageBottom
    // Eğer resim yarıda gözüküyorsa ve sayfa altına kadar kaydırılmamışsa
    // resmin üzerinde "active" sınıfını ekler, aksi halde sınıfı kaldırır.
    if (isHalfShown && isNotScrolledPast) {
      sliderImage.classList.add('active')
    } else {
      sliderImage.classList.remove('active')
    }
 
  })
}
 
// debounce fonksiyonu sayesinde scroll işlemi sırasında sıkça çağrılmasının önüne geçilir
// debounce fonksiyonu sayesinde checkSlide fonksiyonu son scrolldan 20ms sonra çalışacak.
window.addEventListener('scroll', debounce(checkSlide))
 
</script>

Çözümüm (Alternatif)

Daha önce paylaştığım Intersection Observer API ile aynı işlevselliği çok daha basit bir şekilde geliştirdim. Bu çözümde bir debounce fonksiyonuna ihtiyacımız kalmıyor.

<script>
// ============
// 2. VERSIYON
// ============
 
// Tüm resimleri seçelim
const images = document.querySelectorAll(".slide-in");
 
// IntersectionObserver seçeneklerini oluşturalım
const options = {
  threshold: 0.5,// hedef resmin %50'si görünür olduğunda ilgili fonksiyon çalışacaktır.
};
 
const observer = new IntersectionObserver(function (entries, observer) {
  entries.forEach((entry) => {
    // resmin yarısından fazlası görünür olduğunda 'active' sınıfı eklenir.
    if (entry.isIntersecting) {
      entry.target.classList.add("active");
    } else {
      // resmin yarısından fazlası görünmez olduğunda 'active' sınıfı silinir.
      entry.target.classList.remove("active");
    }
  });
}, options);
 
// tüm resimleri IntersectionObserver ile dinler.
images.forEach((image) => {
  observer.observe(image);
});
</script>
GitHubBu sayfayı düzenle