Modern web uygulamalarında kullanıcı deneyimini (UX) en üst düzeye çıkarmanın en etkili yollarından biri, verileri sayfayı yeniden yüklemeden anlık olarak süzebilmektir. Bu rehberimizde, tarayıcı tarafında yüksek performansla çalışan Javascript İle Dinamik İçerik Filtreleme Nasıl Yapılır? sorusuna odaklanacak ve adım adım çalışan bir uygulama geliştireceğiz. Bu eğitim, hem başlangıç düzeyindeki geliştiriciler için temel DOM (Document Object Model - Belge Nesnesi Modeli) manipülasyonunu öğretecek hem de kıdemli geliştiriciler için performans ve güvenlik optimizasyonlarını ele alacaktır.
Geleneksel web uygulamalarında kullanıcılar bir arama yaptığında veya kategori seçtiğinde, sunucuya yeni bir istek gönderilir ve sayfa tamamen yenilenirdi. 2026 yılı web standartlarında ise bu yöntem, kullanıcı kaybına yol açan yavaş bir deneyim olarak kabul edilmektedir. JavaScript kullanarak istemci tarafında (client-side) gerçekleştireceğimiz dinamik filtreleme sayesinde, kullanıcılara milisaniyeler içinde sonuç göstereceğiz. Bu makalede öğreneceğiniz teknikler; e-ticaret sitelerindeki ürün filtreleme sistemlerinde, blog sayfalarındaki arama kutularında ve portfolyo sitelerinde doğrudan kullanılabilir.
Bu eğitim boyunca sadece teorik bilgiyle yetinmeyeceğiz; sıfırdan başlayarak HTML yapısını kuracak, örnek veri setimizi hazırlayacak, metin ve kategori filtrelerini entegre edecek ve son aşamada bu filtreleri birleştirerek performans optimizasyonlarını uygulayacağız. Hazırsanız, modern JavaScript dünyasının bu vazgeçilmez özelliğini kodlamaya başlayalım.
Gereksinimler ve Ön Hazırlık
Geliştireceğimiz dinamik içerik filtreleme uygulamasının sorunsuz çalışabilmesi ve modern standartlara uygun olması için bazı temel gereksinimleri karşılamamız gerekmektedir. Bu projede herhangi bir harici kütüphane (jQuery, React veya Vue gibi) kullanmayacağız; tamamen saf JavaScript (Vanilla JS) ile ilerleyeceğiz. Bu yaklaşım, uygulamanın hafif kalmasını ve tarayıcı tarafından doğrudan en hızlı şekilde yorumlanmasını sağlar.
Uygulamayı geliştirmek ve test etmek için aşağıdaki araçlara ve bilgilere ihtiyacınız olacaktır:
- Kod Editörü: Visual Studio Code, Sublime Text veya WebStorm benzeri modern bir kod editörü.
- Güncel Tarayıcı: JavaScript ES6+ özelliklerini tam destekleyen Google Chrome, Mozilla Firefox, Microsoft Edge veya Safari'nin güncel bir sürümü.
- Temel Bilgi Seviyesi: Temel düzeyde HTML5, CSS3 ve JavaScript (özellikle diziler, nesneler ve olay dinleyiciler) bilgisi.
Geliştirme ortamınızı hazırladıktan sonra, kodlarımızı yazacağımız dizinde index.html, style.css ve app.js adında üç temel dosya oluşturarak ilk adımı atabilirsiniz.
Temel HTML Yapısının Kurulması ve Hazırlık Adımları
Dinamik filtreleme işlemine başlamadan önce, üzerinde filtreleme yapacağımız arayüz elemanlarını ve içerik kartlarını barındıracak HTML yapısını oluşturmamız gerekir. Bu yapıda bir adet arama girdisi (input), kategori butonları ve filtrelenecek elemanların yer alacağı bir kapsayıcı (container) bulunmalıdır.
Aşağıdaki HTML kod bloğu, semantik (anlamsal) web standartlarına uygun olarak tasarlanmıştır. Her bir kartın veri niteliklerini (data attributes) kullanarak hangi kategoriye ait olduğunu belirteceğiz. Bu yöntem, JavaScript tarafında veriye erişmemizi son derece kolaylaştıracaktır.
Javascript İle Dinamik İçerik Filtreleme
Ürün Kataloğu
Yukarıdaki HTML kodunda, id="productGrid" niteliğine sahip olan div elemanı bizim ana sahnemizdir. JavaScript dosyamızda üreteceğimiz dinamik HTML kartları bu alanın içerisine yerleştirilecektir. Ayrıca butonlardaki data-category nitelikleri, filtreleme mantığımızın temelini oluşturacaktır.
Veri Yapısının JavaScript Nesneleri İle Tanımlanması
Gerçek hayattaki uygulamalarda veriler genellikle bir API (Application Programming Interface - Uygulama Programlama Arayüzü) üzerinden JSON formatında gelir. Biz de bu senaryoyu simüle etmek amacıyla, JavaScript dosyamızda ürünlerimizi temsil eden bir nesne dizisi (array of objects) tanımlayacağız.
Her bir ürün nesnesi; benzersiz bir kimlik (id), başlık (title), kategori (category), fiyat (price) ve görsel (image) bilgisi içerecektir. Bu veri yapısı, dinamik olarak HTML şablonlarına dönüştürülerek sayfaya basılacaktır.
// app.js - Örnek veri setinin tanımlanması
const products = [
{ id: 1, title: "Kablosuz Kulaklık", category: "elektronik", price: 1250, image: "https://picsum.photos/id/1/200/150" },
{ id: 2, title: "Akıllı Saat", category: "elektronik", price: 3400, image: "https://picsum.photos/id/2/200/150" },
{ id: 3, title: "JavaScript Başlangıç Rehberi", category: "kitap", price: 180, image: "https://picsum.photos/id/3/200/150" },
{ id: 4, title: "Pamuklu T-Shirt", category: "giyim", price: 450, image: "https://picsum.photos/id/4/200/150" },
{ id: 5, title: "Algoritmalar ve Veri Yapıları", category: "kitap", price: 290, image: "https://picsum.photos/id/5/200/150" },
{ id: 6, title: "Kışlık Mont", category: "giyim", price: 1800, image: "https://picsum.photos/id/6/200/150" }
];
// DOM Elemanlarının Seçilmesi
const productGrid = document.getElementById("productGrid");
const searchInput = document.getElementById("searchInput");
const categoryButtons = document.querySelectorAll(".category-buttons .btn");
Bu veri yapısı, esnek ve genişletilebilir bir yapı sunar. İlerleyen süreçte veri tabanından veya harici bir API'den veri çektiğinizde, sadece bu diziyi güncellemeniz uygulamanın çalışmaya devam etmesi için yeterli olacaktır. DOM elemanlarını en başta seçerek bellek performansını optimize etmiş oluyoruz.
Dinamik İçeriğin DOM Üzerinde Listelenmesi
Verilerimizi tanımladıktan sonra, bu verileri HTML şablonuna dönüştürüp sayfada göstermemiz gerekir. Bu işlem için modern JavaScript'in map() metodunu ve şablon dizilerini (template literals) kullanacağız.
Aşağıdaki fonksiyon, kendisine parametre olarak gönderilen herhangi bir ürün dizisini alır, her bir ürün için HTML kartı oluşturur ve bu kartları tek bir seferde DOM'a ekler. Bu yöntem, her eleman için tek tek DOM'a müdahale etmek yerine (ki bu performansı düşürür), tüm içeriği tek bir seferde yazdırarak tarayıcının render (çizim) yükünü azaltır.
// Ürünleri ekranda listeleyen fonksiyon
function displayProducts(productsToRender) {
if (productsToRender.length === 0) {
productGrid.innerHTML = `Aradığınız kriterlere uygun ürün bulunamadı.
`;
return;
}
const productsHTML = productsToRender.map(product => {
return `
`;
}).join(""); // Diziyi birleştirerek tek bir metin haline getiriyoruz
productGrid.innerHTML = productsHTML;
}
// Uygulama ilk açıldığında tüm ürünleri listele
document.addEventListener("DOMContentLoaded", () => {
displayProducts(products);
});
Yazdığımız displayProducts fonksiyonu, dinamik filtreleme sistemimizin kalbidir. Eğer filtreleme sonucunda eşleşen bir ürün kalmazsa, kullanıcıya dostça bir "Sonuç bulunamadı" mesajı gösterir. join("") metodu, map() fonksiyonunun döndürdüğü dizi elemanları arasındaki virgülleri temizleyerek temiz bir HTML dizesi elde etmemizi sağlar.
Metin Tabanlı Arama Filtrelemesi Nasıl Yapılır?
Kullanıcıların arama kutusuna yazdığı karakterlere göre dinamik olarak içerik süzmek, en yaygın filtreleme yöntemidir. Bu işlem için arama kutusuna bir input olay dinleyicisi (event listener) ekleyeceğiz. input olayı, kullanıcı her tuşa bastığında veya bir metin yapıştırdığında anında tetiklenir.
Arama yaparken büyük-küçük harf duyarlılığını ortadan kaldırmak ve Türkçe karakterlerde sorun yaşamamak için aranan metni ve ürün başlıklarını küçük harfe dönüştürerek karşılaştırma yapmalıyız.
// Metin tabanlı arama fonksiyonu
function filterBySearch(searchTerm, list) {
const cleanSearchTerm = searchTerm.toLowerCase().trim();
return list.filter(product => {
return product.title.toLowerCase().includes(cleanSearchTerm);
});
}
// Arama girdisi için olay dinleyicisi
searchInput.addEventListener("input", (e) => {
const term = e.target.value;
const filtered = filterBySearch(term, products);
displayProducts(filtered);
});
Bu kod bloğunda, trim() metodu ile kullanıcının yanlışlıkla metnin başına veya sonuna koyabileceği boşlukları temizliyoruz. includes() metodu ise aranan kelimenin ürün başlığının herhangi bir yerinde geçip geçmediğini kontrol eder. Bu sayede son derece hızlı ve dinamik bir arama deneyimi elde etmiş oluruz.
Kategori Tabanlı Buton Filtrelemesi Adım Adım Kodlanması
Metin aramasının yanı sıra, kullanıcıların belirli kategorilere tıklayarak içerikleri daraltmasını sağlamak da modern web sitelerinin standart bir özelliğidir. HTML kısmında oluşturduğumuz butonların her birine tıklama olayı tanımlayarak, tıklanan butonun data-category değerine göre filtreleme gerçekleştireceğiz.
Ayrıca, görsel geri bildirim sağlamak amacıyla tıklanan butona aktiflik sınıfı (active) ekleyip diğer butonlardan bu sınıfı kaldıracağız.
// Kategori filtreleme fonksiyonu
function filterByCategory(category, list) {
if (category === "all") {
return list;
}
return list.filter(product => product.category === category);
}
// Kategori butonları için olay dinleyicileri
categoryButtons.forEach(button => {
button.addEventListener("click", (e) => {
// Aktif buton sınıfını güncelle
categoryButtons.forEach(btn => btn.classList.remove("active"));
e.target.classList.add("active");
const selectedCategory = e.target.getAttribute("data-category");
const filtered = filterByCategory(selectedCategory, products);
displayProducts(filtered);
});
});
Burada dikkat edilmesi gereken nokta, "Hepsi" (all) seçeneğidir. Eğer kullanıcı "Hepsi" butonuna tıklarsa, herhangi bir süzme işlemi uygulamadan orijinal listenin tamamını geri döndürüyoruz. Diğer durumlarda ise sadece seçilen kategoriye tam eşit olan ürünleri filtreliyoruz.
Çoklu Filtreleme Mantığının Birleştirilmesi
Gerçek bir senaryoda kullanıcı hem arama kutusuna bir şeyler yazıp hem de aynı anda bir kategori seçebilir. Eğer bu iki filtreyi birbirinden bağımsız çalıştırırsak, kullanıcı kategori seçtiğinde arama kutusundaki metin göz ardı edilir veya tam tersi bir durum yaşanır. Bu sorunu çözmek için "Birleşik Filtreleme" (Combined Filtering) mantığını kurmamız gerekir.
Bunu başarmak için uygulamanın anlık durumunu (state) takip eden değişkenler tanımlayacağız ve her filtreleme olayında bu iki durumu birleştirerek ana listeyi süzgeçten geçireceğiz.
// Uygulama durumunu (state) tutan nesne
const filterState = {
searchQuery: "",
activeCategory: "all"
};
// Hem arama hem de kategori durumuna göre filtreleme yapan ana fonksiyon
function applyCombinedFilters() {
let result = [...products]; // Orijinal dizinin kopyasını alıyoruz
// 1. Adım: Kategori Filtrelemesi
if (filterState.activeCategory !== "all") {
result = result.filter(product => product.category === filterState.activeCategory);
}
// 2. Adım: Metin Arama Filtrelemesi
if (filterState.searchQuery !== "") {
const query = filterState.searchQuery.toLowerCase().trim();
result = result.filter(product => product.title.toLowerCase().includes(query));
}
// Sonucu ekrana yazdır
displayProducts(result);
}
// Arama girdisi olay dinleyicisini güncelle
searchInput.addEventListener("input", (e) => {
filterState.searchQuery = e.target.value;
applyCombinedFilters();
});
// Kategori butonları olay dinleyicilerini güncelle
categoryButtons.forEach(button => {
button.addEventListener("click", (e) => {
categoryButtons.forEach(btn => btn.classList.remove("active"));
e.target.classList.add("active");
filter


Yorumlar (0)
Yorum Yaz