Javascript İle Dinamik Bir Etkileşimli Web Sitesi İstatistik Sayacı Nasıl Yapılır?

Javascript İle Dinamik Bir Etkileşimli Web Sitesi İstatistik Sayacı Nasıl Yapılır?
Javascript İle Dinamik Bir Etkileşimli Web Sitesi İstatistik Sayacı Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Bu projeyi hayata geçirmek için herhangi bir kütüphaneye veya framework'e (React, Vue vb.) ihtiyacınız yoktur. Modern tarayıcılar tarafından desteklenen "Intersection Observer API" ve "requestAnimationFrame" metodlarını kullanarak saf (Vanilla) JavaScript ile en yüksek performansı elde edeceğiz.

  • Modern bir kod editörü (VS Code önerilir).
  • Temel düzeyde HTML5 yapısı.
  • Modern tarayıcı desteği (Chrome, Firefox, Edge, Safari güncel sürümler).
  • Tarayıcı konsolunu kullanarak hata ayıklama yetisi.

Adım 1: İstatistik Sayacı İçin HTML Yapısını Oluşturma

İstatistik sayaçlarının doğru çalışması için verilerin HTML içerisinde "data-target" gibi özel veri öznitelikleri (data attributes) ile tutulması gerekir. Bu, JavaScript'in hangi sayıya kadar sayacağını dinamik olarak okumasını sağlar.

0

Mutlu Müşteri

0

Tamamlanan Proje

Burada data-target özniteliği, sayacın ulaşması gereken nihai değeri temsil eder. HTML içerisinde başlangıç değerini "0" olarak belirledik, böylece JavaScript henüz yüklenmediğinde kullanıcı boş bir alan görmeyecektir.

Adım 2: JavaScript ile Sayaç Mantığını Kurma

Sayaç fonksiyonu, mevcut sayı ile hedef sayı arasındaki farkı hesaplayarak belirli bir hızda artış sağlamalıdır. setInterval yerine requestAnimationFrame kullanmak, animasyonun ekran yenileme hızıyla (60fps) senkronize olmasını sağlar ve CPU kullanımını düşürür.

const counters = document.querySelectorAll('.counter');

counters.forEach(counter => {
  const updateCount = () => {
    const target = +counter.getAttribute('data-target');
    const count = +counter.innerText;
    const increment = target / 200; // Hız ayarı: 200 adımda tamamla

    if (count < target) {
      counter.innerText = `${Math.ceil(count + increment)}`;
      setTimeout(updateCount, 10);
    } else {
      counter.innerText = target;
    }
  };
  updateCount();
});

Bu kod bloğunda, + operatörü ile metin değerini sayıya (integer) dönüştürüyoruz. increment değişkeni, animasyonun ne kadar sürede tamamlanacağını belirleyen bir bölme işlemidir.

Adım 3: Intersection Observer ile Animasyonu Tetikleme

Kullanıcı sayfayı aşağı kaydırdığında sayacın başlaması, profesyonel bir yaklaşım için şarttır. "Intersection Observer API", bir öğenin görünürlük durumunu izlememize olanak tanır.

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // Sayaç fonksiyonunu burada tetikleyin
      updateCount();
    }
  });
});

counters.forEach(counter => observer.observe(counter));

Bu yöntem, animasyonun sadece kullanıcı o bölüme geldiğinde başlamasını sağlar. Böylece animasyon henüz görünür değilken kaynak tüketimi gerçekleşmez.

Adım 4: Performans ve Optimizasyon Karşılaştırması

Farklı yöntemlerin proje üzerindeki etkilerini anlamak için aşağıdaki tabloyu inceleyebilirsiniz:

Yöntem Performans Kullanım Kolaylığı Uyumluluk
setInterval Düşük Yüksek Çok Yüksek
requestAnimationFrame Yüksek Orta Yüksek
CSS Transitions Çok Yüksek Orta Yüksek

Adım 5: Hata Ayıklama ve Yaygın Sorunlar

Sayaç çalışmıyorsa öncelikle tarayıcı konsolunu (F12) kontrol edin. En sık karşılaşılan hata, data-target değerinin sayıya dönüştürülmeden string olarak işleme alınmasıdır. Math.ceil fonksiyonunu kullanarak sayıların tam sayı olarak artmasını sağlayın.

Güvenlik Uyarısı: Kullanıcıdan alınan verileri doğrudan DOM'a yansıtırken innerHTML yerine innerText veya textContent kullanın. Bu, XSS (Cross-Site Scripting) saldırılarına karşı temel bir koruma sağlar.

Adım 6: Üretim Ortamı İçin Geliştirmeler

Gerçek bir projede, sayacın sadece bir kez çalışmasını sağlamak için bir bayrak (flag) değişkeni kullanmalısınız. Aksi takdirde, kullanıcı her yukarı-aşağı kaydırdığında animasyon yeniden başlar ve kötü bir kullanıcı deneyimi oluşturur.

let started = false;

const observer = new IntersectionObserver((entries) => {
  if (entries[0].isIntersecting && !started) {
    counters.forEach(counter => updateCount(counter));
    started = true;
  }
});

Bu yapı, animasyonun sayfa ömrü boyunca sadece bir kez, kullanıcı ilgili alana ilk kez ulaştığında çalışmasını garanti eder.

Sıkça Sorulan Sorular

Sayaç animasyon hızını nasıl değiştirebilirim?

Kod içerisindeki increment değişkenini veya setTimeout süresini değiştirerek hızı artırabilir veya azaltabilirsiniz. Daha büyük bir bölen değeri, animasyonun daha yavaş ilerlemesini sağlar.

Bu sayaç mobil cihazlarda sorun çıkarır mı?

Modern "Intersection Observer" API, mobil tarayıcıların %99'unda desteklenmektedir. Performans sorunu yaşamamak için animasyonları requestAnimationFrame ile yönetmek en güvenli yoldur.

Sayılar neden küsuratlı görünüyor?

JavaScript'te bölme işlemleri sonucu ondalıklı sayılar oluşabilir. Bunu engellemek için Math.ceil() veya Math.floor() fonksiyonlarını kullanarak değerleri tam sayıya yuvarlamanız gerekir.

Aynı sayfada birden fazla sayaç kullanabilir miyim?

Evet, querySelectorAll kullanarak tüm sayaçları bir diziye alabilir ve her biri için ayrı bir döngü veya fonksiyon çağrısı yapabilirsiniz.

İstatistikler veritabanından gelirse ne yapmalıyım?

Verileri bir API üzerinden çekiyorsanız, veriler yüklendikten sonra data-target özniteliğini güncelleyip ardından sayacı başlatmalısınız.

İleri Seviye İpucu: Easing (İvmelenme) Fonksiyonları ile Doğal Animasyon

Doğrusal (linear) bir artış, kullanıcı gözünde mekanik ve yapay bir his bırakabilir. Animasyonun başlangıçta hızlı, sona doğru yavaşlamasını sağlamak için matematiksel "easing" fonksiyonlarını kullanabiliriz. Bu, kullanıcı deneyimini (UX) iyileştiren profesyonel bir dokunuştur.

Aşağıdaki örnekte, requestAnimationFrame içerisinde basit bir "ease-out" mantığı kullanarak sayacın sonlara doğru yavaşlamasını sağlıyoruz:

function easeOutQuad(t) {
  return t * (2 - t);
}

function animateCounter(element, target, duration) {
  let start = null;
  const step = (timestamp) => {
    if (!start) start = timestamp;
    const progress = Math.min((timestamp - start) / duration, 1);
    const easedProgress = easeOutQuad(progress);
    element.innerText = Math.floor(easedProgress * target);
    
    if (progress < 1) {
      window.requestAnimationFrame(step);
    }
  };
  window.requestAnimationFrame(step);
}

Alternatif Yaklaşım: Kütüphane Kullanımı (CountUp.js)

Eğer çok sayıda sayaçla çalışıyorsanız veya animasyonun duraklatılması, tersine çevrilmesi gibi karmaşık özelliklere ihtiyaç duyuyorsanız, tekerleği yeniden icat etmek yerine CountUp.js gibi hafif ve popüler kütüphaneleri tercih edebilirsiniz. Bu kütüphaneler, tarayıcı uyumluluğu ve performans optimizasyonlarını sizin yerinize halleder.

Kütüphane kullanımının avantajlarını şu tabloda görebilirsiniz:

Özellik Manuel JavaScript CountUp.js Kütüphanesi
Kurulum Süresi Kısa Orta (Bağımlılık eklenir)
Dosya Boyutu Çok Düşük (0 KB) Düşük (~3 KB)
Esneklik Tam Kontrol Hazır Fonksiyonlar
Bakım Manuel Güncelleme Otomatik Güncelleme

Kütüphaneyi projenize dahil etmek için CDN üzerinden şu şekilde çağırabilirsiniz:




  const countUp = new CountUp('my-counter-id', 5000);
  if (!countUp.error) {
    countUp.start();
  } else {
    console.error(countUp.error);
  }

Erişilebilirlik (A11y) İçin Kritik Notlar

Dinamik olarak değişen içerikler, ekran okuyucu kullanan görme engelli kullanıcılar için kafa karıştırıcı olabilir. Sayaç animasyonu başladığında ekran okuyucunun sürekli sayıları okuması istenmeyen bir durumdur. Bunu engellemek için aria-live özniteliğini doğru yapılandırmalısınız.

  • aria-live="polite": Ekran okuyucunun mevcut işlemi bitirdikten sonra sayacı okumasını sağlar.
  • aria-hidden="true": Eğer sayaç sadece görsel bir süs ise, ekran okuyucuların bunu görmezden gelmesini sağlayabilirsiniz.

Örnek yapılandırma:

0

Sonuç

JavaScript ile dinamik bir istatistik sayacı oluşturmak, hem teknik becerilerinizi sergilemek hem de sitenizin etkileşimini artırmak için harika bir yöntemdir. Bu rehberde öğrendiğiniz Intersection Observer ve requestAnimationFrame kullanımı, profesyonel web geliştirmede sıkça başvurulan performans odaklı yaklaşımlardır.

Sorumluluk Reddi: Bu makalede paylaşılan kodlar eğitim amaçlıdır. Üretim ortamında kullanmadan önce kodlarınızı güvenlik testlerinden geçirmeyi ve tarayıcı uyumluluklarını (özellikle eski tarayıcılar için Polyfill kullanımı) kontrol etmeyi unutmayın.

Bir sonraki adım olarak, bu sayaçlara "Easing" (ivmelenme) fonksiyonları ekleyerek animasyonların daha doğal bir şekilde durmasını sağlayabilirsiniz. Başarılar dilerim.

Bu yazıya tepkinizi paylaşın:
Zeynep Kaya

Ev ekonomisi ve kişisel organizasyon üzerine birçok yayın yönettim. Okuyucuların günlük yaşam kalitesini artıracak uygulanabilir çözümler üretmeyi hedefliyorum.

Yorumlar (0)

Yorum Yaz