BÖLÜM 1: GİRİŞ VE "ÖĞRENECEKLERİNİZ" PARAGRAFI

Bu kurs, hiç bilmeyen birini ileri seviye bir JavaScript geliştiricisi yapmayı hedefler. Sadece kod yazmayı değil, arka planda nelerin döndüğünü ve bir yazılımcı gibi nasıl problem çözüleceğini öğretir.

Öğrenecekleriniz Paragrafının Detaylı Açıklaması


BÖLÜM 2: JAVASCRIPT TEMELLERİ – KISIM 1 (JAVASCRIPT FUNDAMENTALS – PART 1)

Bu bölümde programlamanın en temel taşları ve JavaScript'in tarayıcı ile ilk teması işlenir.

1. Giriş ve İlk Adımlar (Section Intro, Hello World!, A Brief Introduction to JavaScript)

JavaScript, web sayfalarına canlılık ve etkileşim katan bir programlama dilidir. İlk olarak tarayıcının konsoluna bir yazı yazdırarak dünyaya merhaba deriz.

2. JavaScript Dosyasını Bağlamak (Linking a JavaScript File)

JavaScript kodları HTML dosyasına iki şekilde eklenebilir: Doğrudan HTML içine yazarak ya da dışarıdaki bir .js dosyasını bağlayarak. Gerçek projelerde kodların düzenli olması için dış dosya tercih edilir.

3. Değerler ve Değişkenler (Values and Variables)

Değer, program içindeki en küçük bilgi parçasıdır (Örn: "Ahmet" veya 25). Değişkenler ise bu değerleri içinde sakladığımız etiketli kutulardır.

4. Veri Tipleri (Data Types)

JavaScript'te değerlerin türleri vardır. En temel olanlar: Number (Sayı), String (Yazı), Boolean (Doğru/Yanlış), Undefined (Tanımlanmamış) ve Null (Boş). JavaScript "dinamik tipli" bir dildir, yani bir değişkenin türünü belirtmeniz gerekmez, sistem bunu değerden anlar.

5. Değişken Tanımlama Yolları (let, const and var)

6. Temel Operatörler ve İşlem Önceliği (Basic Operators & Operator Precedence)

Matematiksel (+, -, *, /) ve karşılaştırma (>, <, >=, <=) işlemlerini yapmamızı sağlar. Matematikteki gibi işlemler belirli bir öncelik sırasına göre yapılır.

7. Metinler ve Şablon Dizileri (Strings and Template Literals)

Metinleri birleştirmek için eski yöntemde artı (+) işareti kullanılırdı. Modern JavaScript'te backtick (`) işaretleri kullanılarak yazılan Template Literals ile değişkenler metnin içine doğrudan gömülür.

8. Karar Mekizmaları (Taking Decisions: if / else Statements)

Kodun belirli şartlara göre farklı yollardan gitmesini sağlar. Şart doğruysa if bloğu, yanlışsa else bloğu çalışır.

9. Tip Dönüşümü ve Zorlaması (Type Conversion and Coercion)

10. Doğrusal ve Yanlışsal Değerler (Truthy and Falsy Values)

JavaScript'te tam olarak Boolean (true/false) olmayan ama mantıksal bir sorguya sokulduğunda false gibi davranan 5 değer vardır: 0, "" (boş yazı), undefined, null, NaN. Bunlar dışındaki her şey true kabul edilir.

11. Eşitlik Operatörleri (== vs. ===)

12. Mantıksal Operatörler (Boolean Logic & Logical Operators)

Birden fazla şartı birleştirmek için kullanılır. AND (ve -> &&), OR (veya -> ||), NOT (değil -> !).

13. Switch İfadesi (The switch Statement)

Bir değişkenin çok sayıda farklı değere eşit olma durumunu karmaşık if-else yapıları yerine daha temiz bir şekilde kontrol etmeyi sağlar.

14. İfadeler ve Deyimler (Statements and Expressions)

15. Koşul Operatörü / Ternary (The Conditional Operator)

Tek satırda hızlıca if-else yazmamızı sağlayan üçlü operatördür. şart ? doğruysa_burası : yanlışsa_burası şeklinde çalışır.

16. JavaScript Sürümleri (JavaScript Releases: ES5, ES6+ and ESNext)

JavaScript sürekli gelişen bir dildir. 2015 yılında çıkan ES6 (ECMAScript 6) sürümü dile çağ atlatmıştır. Tarayıcıların eski kodları anlaması için Babel gibi araçlar kullanılır.


BÖLÜM 3: JAVASCRIPT TEMELLERİ – KISIM 2 (JAVASCRIPT FUNDAMENTALS – PART 2)

Bu bölümde kodlarımızı paketlemeyi, veri listeleri oluşturmayı ve döngülerle çalışmayı öğreniriz.

1. Katı Modu Aktif Etmek (Activating Strict Mode)

Kodun en başına yazılan bir metindir. JavaScript'in bazı hataları sessizce geçiştirmesini engeller, konsolda görünür hata verir ve bizi daha güvenli kod yazmaya zorlar.

2. Fonksiyonlar (Functions)

Fonksiyonlar, tekrar tekrar kullanabileceğimiz kod bloklarıdır. İçine veri alabilir (parametre) ve dışarıya bir sonuç fırlatabilir (return).

3. Fonksiyon Tanımlama Türleri (Declarations vs. Expressions vs. Arrow)

Fonksiyon yazmanın üç yolu vardır:

4. Diziler (Introduction to Arrays & Methods)

Diziler, tek bir değişken içinde birden fazla veriyi sıra halinde saklamamızı sağlayan listelerdir. İçerisinde eleman ekleme, çıkarma gibi metotlar barındırır.

5. Nesneler (Introduction to Objects & Notation)

Dizilerde elemanların sırası önemlidir. Nesnelerde ise sıranın önemi yoktur, veriler "Anahtar-Değer" (Key-Value) çiftleri olarak saklanır. Verilere Nokta (.) veya Parantez ([]) yöntemiyle erişilir.

6. Döngüler (Iteration: for & while Loops)

Belirli bir kod bloğunu, bir şart sağlandığı sürece tekrar tekrar çalıştırmak için döngüler kullanılır.


BÖLÜM 4: GELİŞTİRİCİ BECERİLERİ VE EDİTÖR KURULUMU (DEVELOPER SKILLS & EDITOR SETUP)

Kod yazarken hızlanmak ve profesyonel araçları kullanmak bu bölümün temel amacıdır.

1. VS Code ve Prettier Kurulumu

Kodlarımızı yazmak için VS Code editörünü kullanırız. Kodların otomatik olarak süslenmesi, girintilerin ve boşlukların standart hale gelmesi için Prettier eklentisi kurulur.

2. Node.js Ortamı

Tarayıcı dışındaki bilgisayar sisteminde JavaScript çalıştırmak ve terminal araçlarını yönetmek için bilgisayara Node.js kurulur.

3. Hata Ayıklama (Debugging)

Yazılan koddaki mantık hatalarını veya çökmeleri bulma sürecidir. console.log() kullanılarak değişkenlerin anlık değerlerine bakılır. Daha profesyonelce yapmak için tarayıcının inceleme kısmındaki Breakpoints (Durdurma noktaları) kullanılır; kod satır satır durdurularak incelenir.

4. Yapay Zeka Araçlarının Kullanımı (AI Tools)

ChatGPT, GitHub Copilot veya Cursor AI gibi modern yapay zeka araçları kodlama sürecini hızlandırır. Bu araçlara doğru sorular (prompt) sorularak hata çözümleri veya algoritma tasarımları istenir.


BÖLÜM 5: HTML & CSS HIZLANDIRILMIŞ KURS ([OPTIONAL] HTML & CSS CRASH COURSE)

Tarayıcıda JavaScript ile görsel işlemler yapabilmek için web sayfalarının iskeletini ve kıyafetini bilmek gerekir.


BÖLÜM 6: TARAYICIDA JAVASCRIPT: DOM VE EVENTLER (DOM AND EVENTS)

Bu bölüm, JavaScript kullanarak web sayfalarını canlandırdığımız ilk proje bölümüdür. Kurs bu kısımda 3 büyük proje yaptırır: "Numaramı Tahmin Et!", "Açılır Pencere (Modal)" ve "Domuz Oyunu (Pig Game)".

1. DOM Nedir? (Document Object Model)

DOM, HTML sayfasının tarayıcı tarafından oluşturulan bir ağaç haritasıdır. JavaScript bu haritayı kullanarak HTML elementlerini seçebilir, silebilir, değiştirebilir veya yeni element ekleyebilir. DOM tarayıcının bize sunduğu bir özelliktir, saf JavaScript'in bir parçası değildir.

2. Element Seçimi ve Manipülasyonu

3. Olayları Yakalamak (Handling Click Events)

Kullanıcının sayfada yaptığı tıklama, klavyeye basma gibi hareketlere "Event" (Olay) denir. addEventListener ile bu olaylar dinlenir ve gerçekleştiğinde bir fonksiyon tetiklenir.

4. DRY Prensibi ve Kod Yenileme (Refactoring)

DRY (Don't Repeat Yourself - Kendini Tekrar Etme) yazılımın en önemli kuralıdır. Eğer aynı kod bloklarını birden fazla yerde yazdıysanız, o kodları tek bir fonksiyon içine alıp temizleme işlemine Refactoring denir.


BÖLÜM 7: JAVASCRIPT PERDE ARKASI (HOW JAVASCRIPT WORKS BEHIND THE SCENES)

Bu bölüm tamamen teoriktir ve bilgisayar hafızasında nelerin döndüğünü anlatır.

1. JavaScript Motoru ve Çalışma Zamanı (Engine and Runtime)

JavaScript kodlarını bilgisayarın anlayacağı makine koduna çeviren programlara motor denir (Örn: Chrome içindeki V8 motoru). Tarayıcı ise bu motora ek olarak DOM API'lerini ve Event Loop yapısını içeren bir çalışma ortamı (Runtime) sunar.

2. Yürütme Bağlamı ve Çağrı Yığını (Execution Context & Call Stack)

Kod çalışmaya başladığında küresel bir alan (Global Execution Context) oluşur. Her fonksiyon çağrıldığında o fonksiyona ait yeni bir kutu oluşturulur ve Call Stack (Çağrı Yığını) adlı üst üste dizilen bir kuleye konur. İş biten fonksiyon kuleden atılır.

3. Kapsam ve Kapsam Zinciri (Scope and The Scope Chain)

Değişkenlere kodun hangi bölgesinden erişebileceğimizi belirler.

4. Hoisting ve TDZ (Temporal Dead Zone)

JavaScript, kodları çalıştırmadan önce tarar ve değişken tanımlamalarını hafızada en yukarıya taşır gibi davranır. Buna Hoisting denir.

5. 'this' Kelimesi (The 'this' Keyword)

this, o fonksiyonu o an kimin veya hangi nesnenin çalıştırdığını gösteren dinamik bir kelimedir.

6. Bellek Yönetimi: İlkel vs. Nesne Tipleri (Primitives vs. Objects)


BÖLÜM 8: VERİ YAPILARI, MODERN OPERATÖRLER VE METİNLER (DATA STRUCTURES & OPERATORS)

Bu bölüm, verileri çok daha hızlı işlememizi sağlayan modern araçları kapsar.

1. Destructuring (Dizi ve Nesne Parçalama)

Büyük bir dizi veya nesne içindeki verileri tek hamlede çıkarıp ayrı ayrı değişkenlere atama yöntemidir.

2. Spread (...) ve Rest Operatörleri

Üç nokta (...) işareti kullanıldığı yere göre iki farklı işe yarar:

3. Short Circuiting (&&, ||) ve Nullish Coalescing (??) Operatörleri

4. Sets ve Maps (Yeni Veri Yapıları)

5. Gelişmiş Metin Metotları (Working With Strings)

Metinler üzerinde arama yapma, parçalama ve değiştirme fonksiyonlarıdır.


BÖLÜM 9: FONKSİYONLARA YAKINDAN BAKIŞ (A CLOSER LOOK AT FUNCTIONS)

Fonksiyonların gelişmiş özellikleri ve en zor konulardan biri olan Closures (Kapanışlar) burada yer alır.

1. Birinci Sınıf ve Yüksek Dereceli Fonksiyonlar (First-Class & Higher-Order)

JavaScript'te fonksiyonlar birer "değer" gibi görülür. Değişkenlere atanabilir, başka fonksiyonlara parametre olarak gönderilebilir veya bir fonksiyonun içinden dışarıya fonksiyon fırlatılabilir. Başka bir fonksiyonu içine alan ya da dışarıya fonksiyon döndüren yapılara Higher-Order Function denir.

2. Call, Apply ve Bind Metotları

Bir fonksiyonun içindeki this kelimesinin hangi nesneyi göstereceğini dışarıdan zorla belirlemek için kullanılırlar.

3. IIFE (Immediately Invoked Function Expressions)

Tanımlandığı an otomatik olarak hemen çalışan ve bir daha asla çağrılamayan fonksiyonlardır. Geçmişte sadece değişkenleri dış dünyadan gizlemek (kapsüllemek) için kullanılırdı.

4. Kapanışlar (Closures)

Bir fonksiyon, doğduğu ortamdaki (kapsamdaki) değişkenleri, o ortam yok olduktan sonra bile hatırlıyorsa buna Closure denir. Fonksiyon, yaratıldığı yerin değişken ortamına sıkı sıkıya bağlı bir görünmez çanta ile gezer.


BÖLÜM 10: DİZİLERLE ÇALIŞMAK VE BANKIST PROJESİ (WORKING WITH ARRAYS)

Bu bölüm, modern JavaScript projelerinde en çok kullanılan veri dönüştürme metotlarını (map, filter, reduce) "Bankist" adlı görsel bir banka uygulaması üzerinden öğretir.

1. Temel ve Yeni Dizi Metotları

2. Büyük Veri Dönüştürücüler: Map, Filter, Reduce

3. Arama ve Sıralama Metotları


BÖLÜM 11: SAYILAR, TARİHLER VE ZAMANLAYICILAR (NUMBERS, DATES, INTL AND TIMERS)

Web uygulamalarında finansal hesaplar, zaman sayaçları ve dünya standartlarında tarih gösterimleri bu bölümün konusudur.

1. Sayı Güvenliği ve BigInt

JavaScript'te tüm sayılar arkada 64-bitlik kayan noktalı (floating point) sistemle saklanır. Bu yüzden 0.1 + 0.2 tam olarak 0.3 çıkmaz, 0.30000000000000004 çıkar. Çok büyük tam sayılarla hassas hesap yapmak için sayının sonuna n konularak BigInt veri tipi kullanılır.

2. Tarihlerle Çalışmak (Dates)

Zamanı milisaniye cinsinden yönetmek ve tarih objeleri oluşturmak için kullanılır.

3. Uluslararasılaştırma (Intl API)

Web sitenizdeki sayıları veya tarihleri kullanıcının yaşadığı ülkenin dil ve para birimi formatına otomatik çevirir.

4. Zamanlayıcılar (Timers)


BÖLÜM 12: İLERİ SEVİYE DOM VE OLAYLAR (ADVANCED DOM AND EVENTS)

Bu bölümde web sitelerine profesyonel efektler eklemeyi ("Bankist" web sitesi projesi üzerinden) öğreniriz.

1. Olay Kabarcıklanması ve Delege Etme (Bubbling & Event Delegation)

Bir HTML elementine (Örn: bir liste elemanına) tıklandığında, o tıklama olayı sanki suyun altındaki bir hava kabarcığı gibi yukarıdaki tüm ana elementlere (parent) doğru yayılır. Buna Bubbling denir.

2. Intersection Observer API (Gelişmiş Görüş İzleyici)

Kullanıcının sayfayı aşağı kaydırırken belirli bir resme veya bölüme gelip gelmediğini ekran sınırlarına göre tespit eden çok güçlü bir tarayıcı özelliğidir.


BÖLÜM 13: JAVASCRIPT İLE NESNE YÖNELİMLİ PROGRAMLAMA (OOP)

Büyük projeleri sınıflar (Classes) yardımıyla organize etme felsefesidir.

1. Prototip Kalıtımı (Prototypes & Prototypal Inheritance)

JavaScript'teki OOP mimarisi diğer dillerden (Java, C#) farklıdır. JavaScript'te sınıflar aslında arka planda Prototip (Prototype) adı verilen objelere dayanır. Oluşturduğunuz her nesne, bağlı olduğu sınıfın prototipindeki fonksiyonları ortaklaşa kullanır. Bu sayede bilgisayar hafızasından devasa tasarruf sağlanır.

2. ES6 Sınıfları (ES6 Classes)

ES6 ile gelen class kelimesi aslında prototip sisteminin üzerine giydirilmiş süslü bir kıyafettir (Syntactic Sugar). Yazımı çok daha kolay ve temizdir.

3. Kapsülleme ve Gizli Alanlar (Encapsulation: Private Fields)

Dışarıdaki kodların, sınıfın içindeki hassas verilere doğrudan erişip bozmasını engellemek için bazı değişkenler gizlenir. Modern JavaScript'te değişken isminin başına kare (#) işareti konularak o alan Private (Gizli) yapılır.


BÖLÜM 14: MAPTY UYGULAMASI: OOP, COĞRAFİ KONUM VE DIŞ KÜTÜPHANELER (MAPTY PROJECT)

Bu bölümde tamamen nesne yönelimli mimari (OOP) kullanılarak "Mapty" adında bir spor/harita uygulaması geliştirilir.


BÖLÜM 15: ASENKRON JAVASCRIPT: PROMISE, ASYNC/AWAIT VE AJAX

JavaScript normalde tek hat üzerinden sırayla çalışan (Single-threaded, synchronous) bir dildir. Bir işlem uzun sürerse (Örn: internetten büyük veri çekmek) tüm sayfa donar. Bunu önlemek için asenkron yapı kullanılır.

1. AJAX ve API Kavramı

2. Callback Hell ve Promises

Eski yöntemde asenkron işlemleri peş peşe yapmak için fonksiyon içine fonksiyon yazılırdı. Bu durum kodun sağa doğru okunamaz hale gelmesine (Callback Hell - Callback Cehennemi) neden olurdu. Bu sorunu çözmek için Promise (Söz) yapısı getirilmiştir. Promise, gelecekte tamamlanacak bir işlemin sonucunu temsil eder.

3. Async / Await (Modern Asenkron)

Promise yapılarını tıpkı düz, senkron kod yazıyormuş gibi alt alta tertemiz yazmamızı sağlayan en modern ve ödüllü JavaScript özelliğidir. Hataları yakalamak için klasik try...catch blokları kullanılır.

4. Paralel Promises (Promise.all)

Eğer birbirini beklemesi gerekmeyen 3 farklı internet sitesinden aynı anda veri çekeceksek, bunları alt alta yazıp birbirini bekletmek yerine Promise.all ile hepsini aynı anda (paralel) başlatıp hız kazanırız.


BÖLÜM 16: MODERN JAVASCRIPT GELİŞTİRME: MODÜLLER VE ARAÇLAR (MODULES & TOOLING)

Büyük projelerde tüm kodları tek bir .js dosyasına yazmak imkansızdır. Kodları parçalara bölüp yönetmek gerekir.


BÖLÜM 17: FORKIFY UYGULAMASI VE PROJE PLANLAMA (FORKIFY PROJECT)

Kursun en büyük, zirve projesidir. İçinde yemek tarifleri arama, malzeme listelerini porsiyona göre güncelleme, tarif defterine kaydetme ve API'ye yeni tarif yükleme özellikleri olan modern bir yemek platformu inşa edilir.


BÖLÜM 18: GIT KURULUMU VE CANLIYA ALMA (SETTING UP GIT AND DEPLOYMENT)

Yazılan projenin dünyaya sunulma aşamasıdır.

************************************

Modern JavaScript From The Beginning 2.0 kurs müfredatı belgesini satır satır ele alarak, istediğiniz kurallar doğrultusunda tüm konuları derinlemesine inceliyoruz.


"Öğrenecekleriniz" Paragrafının Açıklaması

Bu paragraf, kursu tamamladığınızda kazanacağınız temel ve ileri düzey yazılım yeteneklerini özetler. Kurs, tarayıcıların dinamik olarak çalışmasını sağlayan temel mantıktan başlar. Ardından kodun arka planda nasıl yürütüldüğünü (hafıza yönetimi, asenkron motorlar) ve web sayfalarındaki elemanlara nasıl hükmedebileceğinizi (DOM ve Etkinlikler) öğretir. Sadece kod yazmayı değil; modern endüstri standartlarında kullanılan araçları (Webpack, Babel, NPM), Nesne Yönelimli Programlama (OOP) mimarilerini ve veritabanı bağlantılı (Node, Express, MongoDB) tam donanımlı Full Stack uygulamalar geliştirmeyi vadeder. Gerçek dünya projeleriyle bu teorik bilgileri kalıcı pratiğe dönüştürmeyi amaçlar.


Temel Konuların Tespiti ve Detaylı Açıklamaları

Müfredat satırlarından ayrıştırılan ana konu başlıkları aşağıda listelenmiştir. Her konu teorik altyapısı, kod örneği ve tarayıcıda/Node ortamında doğrudan çalıştırabileceğiniz pratik bir uygulama senaryosu ile ele alınmıştır.

1. JavaScript Nedir, Konsol ve Geliştirici Araçları

JavaScript, web sayfalarına dinamizm ve etkileşim kazandıran, tarayıcılarda doğrudan yorumlanan güçlü bir programlama dilidir. Kodlarımızı test etmek, hataları ayıklamak ve tarayıcıyla iletişim kurmak için geliştirici araçlarında bulunan console (konsol) yapısını kullanırız.

console.log("Sistem başarıyla başlatıldı.");
console.warn("Bu bir uyarı mesajıdır.");
console.error("Kritik bir hata oluştu!");

2. Değişkenler, Sabitler ve Veri Tipleri (Primitive vs Reference)

JavaScript'te verileri hafızada tutmak için değişkenler (let, var) ve değiştirilemeyen sabitler (const) kullanılır. Veri tipleri ikiye ayrılır: İlkel (Primitive) tipler (String, Number, Boolean, Null, Undefined, Symbol) değerleri doğrudan hafızada tutar. Referans (Reference) tipleri (Nesneler, Diziler) ise hafızadaki bir adresi (referansı) işaret eder.

// İlkel Tip Denemesi
let isim1 = "Ahmet";
let isim2 = isim1; // Değer kopyalandı
isim1 = "Mehmet";
console.log(isim2); // Çıktı: "Ahmet" (Etkilenmedi)

// Referans Tip Denemesi
let dizi1 = [1, 2, 3];
let dizi2 = dizi1; // Adres kopyalandı
dizi1.push(4);
console.log(dizi2); // Çıktı: [1, 2, 3, 4] (Etkilendi!)

3. Tip Dönüşümü (Type Conversion) ve Tip Dayatması (Type Coercion)

Tip dönüşümü, yazılımcının bir veriyi bilerek başka bir tipe çevirmesidir (Number(), String()). Tip dayatması ise JavaScript motorunun işlem sırasında veri tiplerini kendi kendine otomatik olarak dönüştürmesidir.

// Manuel Dönüşüm (Conversion)
let metinSayi = "42";
let gercekSayi = Number(metinSayi);
console.log(gercekSayi + 8); // Çıktı: 50

// Otomatik Dayatma (Coercion)
let sonuc = "5" + 5; 
console.log(sonuc); // Çıktı: "55" (Metin birleştirme yaptı)
let fark = "10" - 2;
console.log(fark); // Çıktı: 8 (Çıkarma işleminde sayıya zorladı)

4. Matematik Objesi (Math) ve Tarih İşlemleri (Dates & Times)

Matematiksel karmaşık hesaplamalar için yerleşik Math nesnesi kullanılır. Zaman, saat ve gün yönetimleri ise Date nesnesi ve modern Intl.DateTimeFormat API'leri yardımıyla yerelleştirilerek çözülür.

// Rastgele sayı üretme (1 ile 10 arasında)
let rastgele = Math.floor(Math.random() * 10) + 1;
console.log("Rastgele Sayı: " + rastgele);

// Tarihi Türkçe formatta yazdırma
let bugun = new Date();
let formatliTarih = new Intl.DateTimeFormat('tr-TR', { dateStyle: 'full' }).format(bugun);
console.log("Bugün: " + formatliTarih);

5. Diziler (Arrays) ve Nesneler (Objects)

Diziler, sıralı veri listelerini tutar. Nesneler ise anahtar-değer (key-value) çiftleriyle yapılandırılmış karmaşık veri modelleri oluşturmamızı sağlar. ES6 ile gelen Spread (...) operatörü bu yapıları kopyalamayı ve birleştirmeyi kolaylaştırır. Destructuring ise içlerindeki verileri tek hamlede dışarı çıkarmayı sağlar.

// Nesne ve Destructuring Uygulaması
const kullanici = {
    ad: "Can",
    yas: 28,
    roller: ["Admin", "Yazar"]
};

const { ad, yas } = kullanici; // Destructuring
console.log(`${ad} kişisi ${yas} yaşında.`);

// Spread Operatörü ile Dizi Birleştirme
const Sayilar1 = [1, 2];
const Sayilar2 = [3, 4];
const birlesikDizi = [...Sayilar1, ...Sayilar2];
console.log(birlesikDizi); // Çıktı: [1, 2, 3, 4]

6. Fonksiyonlar, Kapsam (Scope) ve Çalışma Bağlamı (Execution Context)

Fonksiyonlar yeniden kullanılabilir kod bloklarıdır. Kod çalıştırılırken JavaScript motoru bir "Execution Context" (Çalışma Bağlamı) oluşturur. Önce hafıza yerleri ayrılır, sonra kod satır satır işletilir. Kapsam (Scope) ise değişkenlerin nerelerden erişilebilir olduğunu belirler (Global, Function, Block). [1, 2, 3]

const globalDegisken = "Ben her yerdeyim";

function scopeTest() {
    let fonksiyonIci = "Sadece bu fonksiyonda";
    if (true) {
        let blokIci = "Sadece bu if bloğunda";
        var eskiYontem = "Blok dinlemez, fonksiyona sızar";
    }
    // console.log(blokIci); // HATA VERİR!
    console.log(eskiYontem); // Çalışır
}
scopeTest();

7. Mantıksal Akış, Denetimler ve Döngüler

Programın kararlar almasını sağlayan yapılar (if-else, switch, ternary) ve işlemlerin tekrar etmesini sağlayan döngüler (for, while, for...of, for...in) bu başlık altındadır. Ayrıca truthy (doğru kabul edilen) ve falsy (yanlış kabul edilen: 0, "", null, undefined) kavramları akış yönetiminde kritik öneme sahiptir.

// 1'den 15'e kadar dön, 3'ün katlarına Fizz, 5'in katlarına Buzz, ikisinin katına FizzBuzz yaz.
for (let i = 1; i <= 15; i++) {
    if (i % 3 === 0 && i % 5 === 0) {
        console.log("FizzBuzz");
    } else if (i % 3 === 0) {
        console.log("Fizz");
    } else if (i % 5 === 0) {
        console.log("Buzz");
    } else {
        console.log(i);
    }
}

8. Gelişmiş Dizi Yöntemleri (forEach, filter, map, reduce)

Diziler üzerinde döngü kurmak yerine modern JavaScript'te fonksiyonel metotlar tercih edilir. forEach listeyi gezer, filter şartı sağlayanları süzer, map elemanları dönüştürerek yeni dizi üretir, reduce tüm diziyi tek bir değere indirger.

const urunler = [
    { ad: "Kitap", fiyat: 50 },
    { ad: "Kalem", fiyat: 20 },
    { ad: "Defter", fiyat: 80 }
];

// Fiyatı 30'dan büyük olanları filtrele
const pahaliUrunler = urunler.filter(urun => urun.fiyat > 30);
console.log(pahaliUrunler);

// Tüm ürünlerin toplam fiyatını hesapla
const toplamFiyat = urunler.reduce((toplam, urun) => toplam + urun.fiyat, 0);
console.log("Toplam Sepet Tutarı: " + toplamFiyat);

9. Belge Nesnesi Modeli (DOM) Eleman Seçimi ve Yönetimi

DOM, HTML dokümanının JavaScript tarafından okunup değiştirilebilmesini sağlayan bir ağaç yapısıdır. JavaScript ile sayfadaki yazıları, renkleri, butonları seçebilir, silebilir veya yeni dinamik elementler ekleyebiliriz.

// Yeni bir liste elemanı oluşturma ve sayfaya ekleme
const yeniGorev = document.createElement('li');
yeniGorev.innerText = "JavaScript DOM Çalışması Yapılacak";
yeniGorev.className = "gorev-elemani";
yeniGorev.style.color = "blue";

// Sayfadaki mevcut bir elementin içine ekleme (Varsayılan bir ul gövdesine)
document.body.appendChild(yeniGorev);

10. Etkinlikler (Events), Olay Kabarcıklanması ve Delege Etme

Kullanıcının sayfada yaptığı tıklama, klavyeye basma, formu gönderme gibi her hareket bir olaydır (Event). Olay Kabarcıklanması (Event Bubbling), tetiklenen bir olayın en alt elementten en üst elemente doğru yayılmasıdır. Olay Delegasyonu ise performans kazanmak adına etkinlik dinleyicisini alt elemanlara tek tek eklemek yerine ortak üst elemana bağlama tekniğidir.

// Form yakalama ve sayfa yenilenmesini engelleme uygulaması
document.addEventListener('submit', function(etkinlik) {
    etkinlik.preventDefault(); // Sayfa yenilenmesini durdurur
    console.log("Form verileri güvenli şekilde yakalandı.");
});

11. Asenkron JavaScript (Callbacks, Promises, Async/Await, Fetch)

JavaScript tek iş parçacıklı (single-threaded) bir dildir. Zaman alan işlemlerin (internetten veri çekme, dosya okuma vb.) tarayıcıyı dondurmaması için asenkron çalışır. Eskiden Callback fonksiyonları kullanılırken, günümüzde modern Promise yapıları ve kodu senkron gibi yazmamızı sağlayan Async/Await blokları kullanılır. [4, 5]

async function verileriGetir() {
    try {
        console.log("Veri talep ediliyor...");
        // Fetch API ile istek atma
        const yanıt = await fetch('https://typicode.com');
        const veri = await yanıt.json();
        console.log("Gelen Veri Başlığı:", veri.title);
    } catch (hata) {
        console.error("Veri çekilirken sorun oluştu:", hata);
    }
}
verileriGetir();

12. Gelişmiş Tarayıcı API'leri (Web & Browser APIs)

Tarayıcıların bize sunduğu, standart dilin ötesindeki donanımsal ve yazılımsal yeteneklerdir. Kullanıcının konumunu alma (Geolocation), local storage ile verileri tarayıcı hafızasına kalıcı kaydetme, Canvas ile 2D çizim yapma, ses ve video oynatma API'leri bu kapsama girer.

// LocalStorage Veri Kaydetme ve Okuma
localStorage.setItem('kullaniciAdi', 'YazilimGelistirici');

// Sayfa yenilense dahi veriyi geri çekebiliriz
const saklananIsim = localStorage.getItem('kullaniciAdi');
console.log("Kayıtlı Kullanıcı:", saklananIsim);

13. Nesne Yönelimli Programlama (OOP), Prototipler ve Sınıflar

Kod organizasyonunu nesneler üzerinden kurgulama felsefesidir. JavaScript prototip tabanlı bir dildir, yani nesneler yeteneklerini miras kalıtım yoluyla birbirine aktarır. ES6 ile gelen class (sınıf) yapısı, kapsülleme (private fields #), getter/setter metotları OOP mimarisini standartlaştırır.

class Karakter {
    #gizliGuc; // Private mülk (Dışarıdan erişilemez)

    constructor(ad, can) {
        this.ad = ad;
        this.can = can;
        this.#gizliGuc = 100;
    }

    // Metot
    saldir() {
        console.log(`${this.ad} hasar verdi! Kalan gizli gücü: ${this.#gizliGuc}`);
    }
}

const oyuncu1 = new Karakter("Savaşçı", 80);
oyuncu1.saldir(); // Çıktı: Savaşçı hasar verdi!

14. Modüller ve Modern Araç Dünyası (Webpack, Babel, NPM)

Büyük projelerde tüm kodları tek dosyaya yazmak imkansızdır. ES Modülleri (import/export) ile kodlar parçalara ayrılır. NPM, harici kütüphaneleri yönetir. Babel, yazdığımız modern kodları eski tarayıcıların da anlaması için dönüştürür. Webpack ise tüm bu parçaları, CSS ve görselleri tarayıcının hızlıca okuyabileceği tek bir pakete (bundle) dönüştürür.

// matematik.js dosyası içeriği
export function topla(x, y) { return x + y; }

// ana.js dosyası içeriği
import { topla } from './matematik.js';
console.log(topla(10, 20));

15. Veri Yapıları, Algoritmalar ve Birim Testleri (Unit Testing - Jest)

İleri düzey programlamada verilerin bellekte nasıl tutulacağını (Stacks, Queues, Linked Lists) bilmek ve performanslı algoritmalar üretmek gerekir. Yazılan algoritmaların doğru çalışıp çalışmadığını, gelecekte yapılan güncellemelerin sistemi bozup bozmadığını test etmek amacıyla Jest kütüphanesi ile otomatik birim testleri (Unit Testing) yazılır.

// Kodumuz
function palidromKontrol(kelime) {
    return kelime === kelime.split('').reverse().join('');
}

// Jest Test Bloğu (Teorik Gösterim)
// test('Kelime palindrom mu?', () => {
//    expect(palidromKontrol('kabak')).toBe(true);
// });

16. Node.js Temelleri ve REST API Geliştirme (Express & MongoDB)

JavaScript'in sadece tarayıcıda değil, sunucu tarafında da (backend) çalışmasını sağlayan çalışma ortamı Node.js'tir. Dosya sistemi (fs) ve internet protokolleri (http) modülleriyle sunucular kurulur. Express kütüphanesi yardımıyla dış dünyaya veri servis eden modern bir REST API mimarisi inşa edilir. Veriler ise esnek şemaya sahip MongoDB NoSQL veritabanında saklanır.

// Node.js ortamında çalıştırılabilir temel sunucu kurulumu
const http = require('http');

const sunucu = http.createServer((istek, yanit) => {
    yanit.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
    yanit.end('Node.js Backend Sunucusundan Selamlar!');
});

// Sunucu 5000 portunda dinlemeye başlıyor
sunucu.listen(5000, () => {
    console.log("Sunucu çalışıyor: http://localhost:5000");
});



Bütün JavaScript müfredatını kapsayan, bilgisayarınızda adım adım kurup çalıştırabileceğiniz dev bir master rehber hazırladım. Bu yapı, öğrendiğiniz her konuyu tek bir çatı altında test edebilmeniz için modüler bir düzende tasarlanmıştır.

📁 Proje Klasör Yapısı

Bilgisayarınızda modern-js-master adında bir klasör oluşturun. Klasörün iç yapısı tam olarak aşağıdaki gibi görünmelidir:

modern-js-master/
├── package.json
├── webpack.config.js
├── .env
├── server.js
└── src/
    ├── index.html
    ├── index.js
    └── modules/
        ├── 01_konsol.js
        ├── 02_degiskenler.js
        ├── 03_donusumler.js
        ├── 04_matematik_tarih.js
        ├── 05_diziler_nesneler.js
        ├── 06_fonksiyonlar_scope.js
        ├── 07_akıs_donguler.js
        ├── 08_gelişmiş_diziler.js
        ├── 09_dom_yonetimi.js
        ├── 10_etkinlikler.js
        ├── 11_asenkron.js
        ├── 12_tarayıcı_api.js
        ├── 13_oop_siniflar.js
        └── 15_algoritmalar.js

⚙️ Kurulum Adımları (Adım Adım)

Projeyi bilgisayarınızda ayağa kaldırmak için terminal veya komut satırını açıp şu komutları sırasıyla uygulayın:

1. Proje Klasörünü Oluşturun ve İçine Girin:

mkdir modern-js-master
cd modern-js-master

2. Node.js Projesini Başlatın:

npm init -y

3. Gerekli Bağımlılıkları (Paketleri) Yükleyin:
Bu komut hem Backend (Express) hem de Frontend paketleme (Webpack, Babel) araçlarını yükler.

npm install express dotenv cors
npm install --save-dev webpack webpack-cli webpack-dev-server html-webpack-plugin babel-loader @babel/core @babel/preset-env jest

🛠️ Yapılandırma Dosyaları

package.json Dosyası

Dosyanızı açın ve scripts bölümünü aşağıdaki gibi güncelleyin:

{
  "name": "modern-js-master",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": {
    "frontend:dev": "webpack serve --mode development",
    "frontend:build": "webpack --mode production",
    "backend:start": "node server.js",
    "test": "jest"
  },
  "dependencies": {
    "cors": "^2.8.5",
    "dotenv": "^16.4.5",
    "express": "^4.19.2"
  },
  "devDependencies": {
    "@babel/core": "^7.24.5",
    "@babel/preset-env": "^7.24.5",
    "babel-loader": "^9.1.3",
    "html-webpack-plugin": "^5.6.0",
    "jest": "^29.7.0",
    "webpack": "^5.91.0",
    "webpack-cli": "^5.1.4",
    "webpack-dev-server": "^5.0.4"
  }
}

webpack.config.js Dosyası

Kök dizinde bu dosyayı oluşturun. Frontend kodlarımızı birleştirecektir.

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    clean: true,
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: { presets: ['@babel/preset-env'] },
        },
      },
    ],
  },
  devServer: {
    port: 3000,
    open: true,
    hot: true,
  },
};

.env Dosyası

Arka plan ayarları için kök dizine ekleyin:

PORT=5000

🖥️ Sunucu (Backend) Kodu

server.js Dosyası

Kursun son aşamasındaki Node.js, Express ve API mantığını çalıştıran merkez üssüdür.

const express = require('express');
const cors = require('cors');
require('dotenv').config();

const app = express();
const PORT = process.env.PORT || 5000;

app.use(cors());
app.use(express.json());

// Örnek sahte veritabanı (Müfredattaki REST API konusu için)
let fikirler = [
  { id: 1, baslik: "JavaScript Öğren", yazar: "Asım" },
  { id: 2, baslik: "Webpack Ayarla", yazar: "Deniz" }
];

// GET İsteği
app.get('/api/fikirler', (req, res) => {
  res.json(fikirler);
});

// POST İsteği
app.post('/api/fikirler', (req, res) => {
  const yeniFikir = { id: Date.now(), baslik: req.body.baslik, yazar: "Anonim" };
  fikirler.push(yeniFikir);
  res.status(201).json(yeniFikir);
});

app.listen(PORT, () => {
  console.log(`Backend API çalışıyor: http://localhost:${PORT}`);
});

🎨 Arayüz (Frontend) Kodları

src/index.html Dosyası

DOM ve Etkinlikler konularının tarayıcıda hayat bulacağı HTML şablonumuz.

<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Modern JS Master Projesi</title>
    <style>
        body { font-family: sans-serif; margin: 30px; background: #f4f4f9; }
        .kutu { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); margin-bottom: 20px; }
        button { padding: 10px 15px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; }
        button:hover { background: #0056b3; }
    </style>
</head>
<body>
    <h1>Modern JavaScript Müfredat Uygulaması</h1>
    <p>Konsolu (F12) açarak arka plandaki tüm JS çıktılarının çalışmasını izleyebilirsiniz.</p>

    <!-- DOM ve Etkinlik Kutusu -->
    <div class="kutu" id="dom-kutusu">
        <h2 id="ana-baslik">DOM ve Etkinlik Alanı</h2>
        <button id="renk-butonu">Arka Plan Rengini Değiştir</button>
        <ul id="gorev-listesi"></ul>
    </div>

    <!-- API Veri Kutusu -->
    <div class="kutu">
        <h2>Backend Rest API Bağlantısı</h2>
        <button id="api-veri-butonu">API'den Fikirleri Çek</button>
        <ul id="api-listesi"></ul>
    </div>
</body>
</html>

src/index.js Dosyası

Bütün JavaScript modüllerimizi (konularını) Webpack dünyasına bağlayan ana damardır.

// Müfredat konularını sırayla içeri aktarıyoruz (Modül Sistemi)
import './modules/01_konsol.js';
import './modules/02_degiskenler.js';
import './modules/03_donusumler.js';
import './modules/04_matematik_tarih.js';
import './modules/05_diziler_nesneler.js';
import './modules/06_fonksiyonlar_scope.js';
import './modules/07_akıs_donguler.js';
import './modules/08_gelişmiş_diziler.js';
import './modules/09_dom_yonetimi.js';
import './modules/10_etkinlikler.js';
import './modules/11_asenkron.js';
import './modules/12_tarayıcı_api.js';
import './modules/13_oop_siniflar.js';

📦 Konu Modüllerinin İçerikleri (src/modules/)

Aşağıdaki kodların her birini src/modules/ klasörünün altında ilgili dosya isimleriyle oluşturun.

01_konsol.js (Konsol Kullanımı)

console.log("--- Konu 1: Konsol ---");
console.warn("Bu bir uyarı mesajıdır.");
console.error("Bu bir hata simülasyonudur.");

02_degiskenler.js (Primitive vs Reference)

console.log("--- Konu 2: Değişken Tipleri ---");
let sayi1 = 10;
let sayi2 = sayi1; 
sayi1 = 20;
console.log("İlkel Kopya (Değişmez):", sayi2); // 10

let dizi1 =;
let dizi2 = dizi1;
dizi1.push(3);
console.log("Referans Kopya (Değişir!):", dizi2); // [1, 2, 3]

03_donusumler.js (Type Conversion & Coercion)

console.log("--- Konu 3: Tip Dönüşümleri ---");
let metin = "100";
console.log("Dönüşüm:", Number(metin) + 50); // 150
console.log("Dayatma (Coercion):", "5" + 5); // "55"

04_matematik_tarih.js (Math & Date)

console.log("--- Konu 4: Math ve Tarih ---");
console.log("Rastgele Sayı (1-10):", Math.floor(Math.random() * 10) + 1);
const bugun = new Date();
console.log("Formatlı Tarih:", new Intl.DateTimeFormat('tr-TR').format(bugun));

05_diziler_nesneler.js (Destructuring & Spread)

console.log("--- Konu 5: Diziler ve Nesneler ---");
const kisi = { ad: "Hasan", yas: 32 };
const { ad } = kisi; // Destructuring
console.log("Destructure Edilen Ad:", ad);

const eskiDizi =;
const yeniDizi = [...eskiDizi, 3, 4]; // Spread Operatörü
console.log("Birleşik Dizi:", yeniDizi);

06_fonksiyonlar_scope.js (Arrow Functions & Scope)

console.log("--- Konu 6: Fonksiyonlar ve Kapsam ---");
const karesi = (x) => x * x; // Arrow Function
console.log("9'un Karesi:", karesi(9));

if (true) {
    let blokDegiskeni = "Sadece buraya ait";
    var fonksiyonSizintisi = "Blok dışına taşar";
}
console.log("Sızıntı Kontrolü:", fonksiyonSizintisi);

07_akıs_donguler.js (Logic & FizzBuzz)

console.log("--- Konu 7: Döngüler (FizzBuzz) ---");
let sonuclar = [];
for (let i = 1; i <= 5; i++) {
    if (i % 3 === 0) sonuclar.push("Fizz");
    else sonuclar.push(i);
}
console.log("FizzBuzz İlk 5 Adım:", sonuclar);

08_gelişmiş_diziler.js (Map, Filter, Reduce)

console.log("--- Konu 8: Gelişmiş Dizi Metotları ---");
const rakamlar =;
const ciftler = rakamlar.filter(n => n % 2 === 0);
const karesiDizi = rakamlar.map(n => n * 2);
const toplam = rakamlar.reduce((acc, curr) => acc + curr, 0);
console.log("Filtre, Map, Reduce Çıktıları:", { ciftler, karesiDizi, toplam });

09_dom_yonetimi.js (DOM Modifikasyonu)

// Tarayıcı yüklenince sayfaya eleman ekler
window.addEventListener('DOMContentLoaded', () => {
    const liste = document.getElementById('gorev-listesi');
    if(liste) {
        const yeniGorev = document.createElement('li');
        yeniGorev.innerText = "Müfredat Görevi 1: DOM Başarıyla Öğrenildi!";
        liste.appendChild(yeniGorev);
    }
});

10_etkinlikler.js (Event Listeners)

window.addEventListener('DOMContentLoaded', () => {
    const buton = document.getElementById('renk-butonu');
    const kutu = document.getElementById('dom-kutusu');
    
    if(buton && kutu) {
        buton.addEventListener('click', () => {
            kutu.style.backgroundColor = kutu.style.backgroundColor === 'bisque' ? 'white' : 'bisque';
            console.log("Butona tıklandı: Arka plan değişti.");
        });
    }
});

11_asenkron.js (Async / Await)

console.log("--- Konu 11: Asenkron JavaScript ---");
const gecikmeliVeri = () => new Promise(resolve => setTimeout(() => resolve("Veri Geldi!"), 1000));

async function akis() {
    console.log("İstek başladı...");
    const sonuc = await gecikmeliVeri();
    console.log("Asenkron Sonuç:", sonuc);
}
akis();

12_tarayıcı_api.js (LocalStorage)

console.log("--- Konu 12: Tarayıcı API (LocalStorage) ---");
localStorage.setItem('kurs_durumu', 'Devam Ediyor');
console.log("Kayıttan Okunan Veri:", localStorage.getItem('kurs_durumu'));

13_oop_siniflar.js (OOP & Classes)

console.log("--- Konu 13: OOP ve Sınıflar ---");
class Kurs {
    constructor(ad) {
        this.ad = ad;
    }
    selamla() {
        return `${this.ad} kursuna hoş geldiniz!`;
    }
}
const jsKursu = new Kurs("Modern JavaScript 2.0");
console.log(jsKursu.selamla());

🧪 Algoritmalar ve Test Ortamı (src/modules/15_algoritmalar.js)

Müfredattaki Unit Testing (Jest) konusunu test etmek için kök dizinde bir algoritma fonksiyonu hazırlayalım.

src/modules/15_algoritmalar.js Dosyası

function tersCevir(metin) {
    return metin.split('').reverse().join('');
}
module.exports = tersCevir;

src/modules/15_algoritmalar.test.js Dosyası (Test Dosyası)

Aynı klasörde .test.js uzantılı bir dosya açın:

const tersCevir = require('./15_algoritmalar');

test('Metni doğru şekilde ters çeviriyor mu?', () => {
    expect(tersCevir('hello')).toBe('olleh');
    expect(tersCevir('js')).toBe('sj');
});

🚀 Sistemi Çalıştırma Talimatları

Her şey hazır! Şimdi 3 farklı terminal sekmesi açarak tüm sistemi tam entegre şekilde ayağa kaldırın:

  1. Terminal 1 (Backend API Sunucusunu Başlatın):

    npm run backend:start

    Ekranınızda Backend API çalışıyor: http://localhost:5000 yazacaktır.

  2. Terminal 2 (Frontend Webpack Sunucusunu Başlatın):

    npm run frontend:dev

    Tarayıcınız otomatik olarak http://localhost:3000 adresinde açılacaktır. F12 tuşuna basıp Konsol (Console) sekmesinde tüm konuların çıktılarını görebilirsiniz.

  3. Terminal 3 (Jest Algoritma Testlerini Çalıştırın):

    npm run test

    Yazdığınız tersCevir algoritmasının test edilip başarıyla geçtiğini (PASS) yeşil renkli raporla göreceksiniz.


*******************************

Verdiğiniz kurs müfredatı belgesini satır satır ve bölüm bölüm inceleyerek, tüm konuları hiçbir özet yapmadan, en detaylı şekilde hazırladım. İstediğiniz gibi süreleri, "Önizleme" yazılarını ve "ders" satırlarını tamamen temizledim.

Bu rehber, JavaScript dilini sıfırdan ileri seviyeye kadar uygulamalarla öğrenmenizi sağlayacak dev bir kaynak niteliğindedir.


JavaScript Kursu Detaylı Eğitim Rehberi

Öğrenecekleriniz

Bu kursun temel amacı, sizi sadece teorik bilgiyle bırakmak yerine JavaScript dilini gerçek projeler inşa ederek (30'dan fazla proje) öğretmektir. Kurs boyunca web sayfalarının canlandırılmasını (DOM yönetimi), modern JavaScript standartlarını (ES6+), tarayıcı hafızasını (Local Storage), internet üzerinden veri alışverişini (API, AJAX, Async/Await) ve büyük ölçekli uygulamaların mimarisini (Nesne Yönelimli Programlama - OOP) uygulamalı olarak öğreneceksiniz.


1. Geliştirme Ortamının Kurulması ve Araçlar

Yazılım geliştirmeye başlamak için doğru araçları kurmak ve bunları verimli kullanmayı öğrenmek gerekir.


2. JavaScript Temelleri (Basics)

JavaScript dilinin en temel yapı taşları, kuralları ve veri tipleri bu bölümde işlenmektedir.

Kodun Sayfaya Eklenme Yöntemleri

Yardımcı Metotlar, İfadeler ve Yorum Satırları

Değişkenler (Variables) ve İsimlendirme Kuralları

Değişkenler, program içinde verileri sakladığımız kutulardır.

Veri Tipleri ve Metin İşlemleri (Strings & Numbers)

Diziler ve Fonksiyonlar (Arrays & Functions)

Objeler (Objects)

Objeler, içerisinde özellikler (property) ve metotlar (fonksiyonlar) barındıran gelişmiş yapılardır. Bir anahtar (key) ve bir değer (value) ilişkisiyle çalışır.

let araba = {
    marka: "Toyota",
    model: "Corolla",
    calistir: function() { console.log("Araba çalıştı."); }
};
console.log(araba.marka); // Çıktı: Toyota

Koşullu İfadeler ve Döngüler (Conditionals & Loops)


3. İleri Seviye JavaScript ve Dizi İşlemleri (Continued)

String ve Array Metotları

Kapsam (Scope) ve Gelişmiş Fonksiyonlar

Dizi Döngüleri (Array Iterators)

Diziler üzerinde dönerek verileri manipüle etmemizi sağlayan modern fonksiyonlardır.


4. DOM (Document Object Model) Yönetimi

DOM, tarayıcının HTML sayfasını JavaScript ile kontrol edebilmemiz için oluşturduğu bir ağaç yapısıdır. Bu bölüm sayesinde sayfadaki yazıları, renkleri ve butonları dinamik olarak değiştirebiliriz.

Eleman Seçimi ve Navigasyon

Eleman Değiştirme ve Oluşturma

Olaylar (Events) ve Tarayıcı Depolama


5. Projeler Bölümü - 1: Temel DOM Projeleri

Bu bölümde öğrendiğimiz tüm temeller pratik projelere dökülmektedir.

Uygulama 1: Color Flipper (Renk Değiştirici)

Uygulama 2: Counter (Sayaç)

Uygulama 3: Reviews (Müşteri Yorumları Sayfası)

Uygulama 4: Navbar & Sidebar (Açılır Menüler)

Uygulama 5: Modal (Açılır Pencere)

Uygulama 6: Questions (Sıkça Sorulan Sorular / Akordeon)

Uygulama 7: Menu (Kategorili Restoran Menüsü)

Uygulama 8: Video (Arka Plan Video Kontrolü)

Uygulama 9: Scroll (Dinamik Kaydırma Menüsü)

Uygulama 10: Tabs (Sekmeli İçerik Yapısı)

Uygulama 11: Countdown (Geri Sayım Sayacı)

Uygulama 12: Lorem Ipsum Generator (Rastgele Metin Üretici)

Uygulama 13: Grocery Bud (Yapılacaklar / Alışveriş Listesi)

Uygulama 14: Slider (Görsel Kaydırıcı)


6. Projelerin Dağıtımı (Deployment)

Yaptığımız web projelerini tüm dünyanın görebileceği şekilde internete yükleme sürecidir.


7. Nesne Yönelimli Programlama (OOP) ve Objeler

Büyük projeleri organize etmek için kodları nesneler halinde tasarlama yaklaşımıdır.


8. OOP Projeleri

Uygulama 15: Nesne Yönelimli Sayaç (Counter - Class Refactor)

Uygulama 16: Gelişmiş Resim Galerisi (Gallery - Class Refactor)


9. Fonksiyonların Derinlikleri (Functions)


10. Modern JavaScript (ES6+) Özellikleri

JavaScript'i modern, hızlı ve az kodla yazmamızı sağlayan yeniliklerdir.


11. Projeler Bölümü - 2: ES6 Projeleri

Uygulama 17: Animasyonlu Sayılar (Numbers)

Uygulama 18: Koyu Tema Modu (Dark Mode)

Uygulama 19: Dinamik Ürün Filtreleme (Filters)


12. JavaScript Modülleri (Modules)

Kodları tek bir dev dosya yerine mantıksal küçük dosyalara bölme sistemidir.


13. Asenkron JavaScript ve AJAX (Async JS & AJAX)

JavaScript normalde satır satır ve sırayla çalışır (Synchronous). Ancak internetten veri çekme gibi uzun süren işlemlerin sayfayı dondurmaması için asenkron (Asynchronous) çalışması gerekir.


14. Projeler Bölümü - 3: API ve AJAX Projeleri

Artık dış dünyadaki gerçek sunuculara bağlanıp canlı veriler çektiğimiz aşamadır.

Uygulama 20: Dad Jokes (Rastgele Espri Üretici)

Uygulama 21: Products (E-Ticaret Ürün Listesi ve Detay Sayfası)

Uygulama 22: Random User (Rastgele Kullanıcı Kartı)

Uygulama 23: Cocktails (Kokteyl Ansiklopedisi ve Arama)


15. İleri Düzey Kompleks Projeler

Kursun zirve noktası olan, tüm bilgilerin harmanlandığı büyük ölçekli projelerdir.

Uygulama 24: Gelişmiş Slider

Uygulama 25: Stripe Menü Mimarisi (Stripe Submenus)

Uygulama 26: Pagination (Sayfalama Sistemi)

Uygulama 27: Wikipedia Arama Motoru (Wikipedia API)

Uygulama 28: Comfy Store (Tam Donanımlı E-Ticaret Sitesi)




Müfredatta yer alan ve gerçek dünya JavaScript mantığını kurmanızı sağlayacak tüm benzersiz projeleri (tam 22 farklı uygulama mimarisini), hiçbirini atlamadan, en temel seviyeden en ileri seviyeye doğru adım adım kodlayalım.

Her projenin mantığını anlamanız için dosyaları HTML (Yapı), CSS (Görünüm) ve JavaScript (Zeka) olarak ayırarak, 4. sınıf düzeyinde bir dille, en açık şekilde hazırladım.


BÖLÜM 1: TEMEL DOM PROJELERİ

Proje 1: Color Flipper (Renk Değiştirici)

Mantık: Bilgisayarlar renkleri Hex kodu adı verilen ve # işaretiyle başlayan 6 haneli karakterlerle tanır (Örn: #FFFFFF beyazdır). Bu projede bir butona basıldığında arka planı rastgele boyayacağız.

index.html

<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <title>Renk Değiştirici</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <h2>Arka Plan Rengi: <span id="renk-kodu">#FFFFFF</span></h2>
        <button id="renk-btn">Rengi Değiştir</button>
    </div>
    <script src="app.js"></script>
</body>
</html>

style.css

body {
    font-family: sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    transition: background-color 0.3s ease; /* Renk geçişini yumuşatır */
}
.container {
    text-align: center;
    background: white;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
button {
    padding: 10px 20px;
    font-size: 16px;
    cursor: pointer;
}

app.js

// 1. Kullanacağımız karakterleri bir kutuya (diziye) koyalım
const hexKarakterleri = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F"];

// 2. HTML'deki elemanları seçelim
const buton = document.getElementById("renk-btn");
const renkYazisi = document.getElementById("renk-kodu");

// 3. Butona tıklanınca ne olacağını yazalım
buton.addEventListener("click", function() {
    let hexKodu = "#";
    
    // Döngü kurarak rastgele 6 karakter seçelim
    for (let i = 0; i < 6; i++) {
        const rastgeleSira = Math.floor(Math.random() * hexKarakterleri.length);
        hexKodu += hexKarakterleri[rastgeleSira];
    }
    
    // Sayfanın rengini ve yazısını değiştirelim
    document.body.style.backgroundColor = hexKodu;
    renkYazisi.textContent = hexKodu;
});

Proje 2: Counter (Gelişmiş Sayaç)

Mantık: Ekrandaki sayıyı artırıp azaltacağız. Sayı pozitifse yeşil, negatifse kırmızı, sıfırsa siyah olacak.

index.html

<div class="sayaç-kutusu">
    <h1 id="deger">0</h1>
    <button class="btn azalt">Azalt</button>
    <button class="btn sifirla">Sıfırla</button>
    <button class="btn artir">Artır</button>
</div>

app.js

let sayi = 0;
const deger = document.getElementById("deger");
const butonlar = document.querySelectorAll(".btn");

butonlar.forEach(function(buton) {
    buton.addEventListener("click", function(olay) {
        // Tıklanan butonun hangi sınıfa sahip olduğuna bakalım
        const siniflar = olay.currentTarget.classList;
        
        if (siniflar.contains("azalt")) {
            sayi--;
        } else if (siniflar.contains("artir")) {
            sayi++;
        } else {
            sayi = 0;
        }
        
        // Renk kontrolü yapalım
        if (sayi > 0) { deger.style.color = "green"; }
        if (sayi < 0) { deger.style.color = "red"; }
        if (sayi === 0) { deger.style.color = "black"; }
        
        deger.textContent = sayi;
    });
});

Proje 3: Reviews (Müşteri Yorumları)

Mantık: Elimizde müşterilerin bilgilerini içeren bir veri listesi var. İleri ve geri butonlarına basarak bu listede gezineceğiz.

app.js

// Müşteri verilerimiz
const yorumlar = [
    { id: 1, isim: "Ayşe Yılmaz", iş: "Tasarımcı", resim: "https://picsum.photos", yazi: "Harika bir hizmet, çok memnun kaldım!" },
    { id: 2, isim: "Ahmet Kaya", iş: "Geliştirici", resim: "https://picsum.photos", yazi: "Kodlar çok temiz ve anlaşılır." }
];

let aktifSira = 0;

// Elemanları seçelim
const resim = document.getElementById("musteri-resim");
const isim = document.getElementById("musteri-isim");
const is = document.getElementById("musteri-is");
const yazi = document.getElementById("musteri-yazi");

const geriBtn = document.querySelector(".geri-btn");
const ileriBtn = document.querySelector(".ileri-btn");

// Ekrana veriyi basan fonksiyon
function musteriGoster(sira) {
    const eleman = yorumlar[sira];
    resim.src = eleman.resim;
    isim.textContent = eleman.isim;
    is.textContent = eleman.iş;
    yazi.textContent = eleman.yazi;
}

ileriBtn.addEventListener("click", function() {
    aktifSira++;
    if (aktifSira > yorumlar.length - 1) {
        aktifSira = 0; // Başa dön
    }
    musteriGoster(aktifSira);
});

geriBtn.addEventListener("click", function() {
    aktifSira--;
    if (aktifSira < 0) {
        aktifSira = yorumlar.length - 1; // Sona git
    }
    musteriGoster(aktifSira);
});

Proje 4: Navbar & Sidebar (Açılır Menüler)

Mantık: CSS'te menüyü ekranın soluna gizleyeceğiz (transform: translateX(-100%)). JavaScript ile butona basıldığında bir sınıf ekleyip menüyü ekrana getireceğiz.

app.js

const menüButonu = document.querySelector(".menu-toggle");
const yanMenu = document.querySelector(".sidebar");
const kapatButonu = document.querySelector(".close-btn");

menüButonu.addEventListener("click", function() {
    // Sınıf varsa siler, yoksa ekler
    yanMenu.classList.toggle("show-sidebar");
});

kapatButonu.addEventListener("click", function() {
    yanMenu.classList.remove("show-sidebar");
});

Proje 5: Modal (Açılır Pencere)

Mantık: Sayfanın üzerinde beliren bir bilgi kutusu (popup) yapacağız.

app.js

const acBtn = document.querySelector(".modal-btn");
const kapaBtn = document.querySelector(".close-btn");
const kaplama = document.querySelector(".modal-overlay");

acBtn.addEventListener("click", function() {
    kaplama.classList.add("open-modal");
});

kapaBtn.addEventListener("click", function() {
    kaplama.classList.remove("open-modal");
});

Proje 6: Questions (Akordeon SSS Soru-Cevap)

Mantık: Bir soruya tıklandığında cevabı açılacak, diğer açık olan sorular ise otomatik kapanacak.

app.js

const sorular = document.querySelectorAll(".question");

sorular.forEach(function(soru) {
    const buton = soru.querySelector(".question-btn");
    
    buton.addEventListener("click", function() {
        // Diğer açık soruları kapatma döngüsü
        sorular.forEach(function(item) {
            if (item !== soru) {
                item.classList.remove("show-text");
            }
        });
        
        soru.classList.toggle("show-text");
    });
});

Proje 7: Restoran Menüsü (Dinamik Kategorili Filtreleme)

Mantık: Yemek listesindeki verileri kategorilere ayırıp, butonlara basıldığında sadece o kategorideki yemekleri süzüp ekrana basacağız.

app.js

const menu = [
    { id: 1, baslik: "Krep", kategori: "kahvalti", fiyat: 45, icerik: "Harika çilekli krep." },
    { id: 2, baslik: "Burger", kategori: "ogle", fiyat: 120, icerik: "Nefis dana köfteli burger." }
];

const menuAlani = document.querySelector(".section-center");
const butonAlani = document.querySelector(".btn-container");

// Sayfa ilk yüklendiğinde çalışacak kodlar
window.addEventListener("DOMContentLoaded", function() {
    menuyuEkranaBas(menu);
    kategoriButonlariHazirla();
});

function menuyuEkranaBas(menuElemanlari) {
    let ekranHtml = menuElemanlari.map(function(item) {
        return `<article class="menu-item">
            <div class="item-info">
                <header>
                    <h4>${item.baslik}</h4>
                    <h4 class="price">${item.fiat} TL</h4>
                </header>
                <p class="item-text">${item.icerik}</p>
            </div>
        </article>`;
    });
    ekranHtml = ekranHtml.join("");
    menuAlani.innerHTML = ekranHtml;
}

function kategoriButonlariHazirla() {
    // Benzersiz kategorileri bulalım (kahvalti, ogle vb.)
    const kategoriler = ["hepsi", ...new Set(menu.map(item => item.kategori))];
    
    const filtreButonlari = kategoriler.map(function(kat) {
        return `<button class="filter-btn" data-id="${kat}">${kat}</button>`;
    }).join("");
    
    butonAlani.innerHTML = filtreButonlari;
    const butonlar = butonAlani.querySelectorAll(".filter-btn");
    
    // Butonlara tıklanınca filtreleme yapalım
    butonlar.forEach(function(btn) {
        btn.addEventListener("click", function(e) {
            const kategoriIsmi = e.currentTarget.dataset.id;
            const filtrelenmişMenu = menu.filter(function(menuItem) {
                if (menuItem.kategori === kategoriIsmi) {
                    return menuItem;
                }
            });
            
            if (kategoriIsmi === "hepsi") {
                menuyuEkranaBas(menu);
            } else {
                menuyuEkranaBas(filtrelenmişMenu);
            }
        });
    });
}

Proje 8: Video Kontrolü ve Yükleme Ekranı (Preloader)

Mantık: Arka plan videosunu durdurup oynatacağız. Sayfa tamamen hazır olana kadar da ekranda bir yükleniyor animasyonu göstereceğiz.

app.js

const btn = document.querySelector(".switch-btn");
const video = document.querySelector(".video-container");
const yukleniyor = document.querySelector(".preloader");

// Oynat - Durdur butonu
btn.addEventListener("click", function() {
    if (!btn.classList.contains("slide")) {
        btn.classList.add("slide");
        video.pause(); // Videoyu durdur
    } else {
        btn.classList.remove("slide");
        video.play(); // Videoyu oynat
    }
});

// Sayfa tamamen yüklendiğinde animasyonu gizle
window.addEventListener("load", function() {
    yukleniyor.classList.add("hide-preloader");
});

Proje 9: Scroll (Dinamik Sabit Menü ve Pürüzsüz Kaydırma)

Mantık: Sayfa aşağı kayınca navbar yukarı yapışacak. Menü linklerine tıklayınca ilgili bölüme tam ölçüyle pürüzsüz kayacak.

app.js

const navbar = document.getElementById("nav");
const yukariButon = document.querySelector(".top-link");

window.addEventListener("scroll", function() {
    const kaymaMiktari = window.pageYOffset;
    const navbarYuksekligi = navbar.getBoundingClientRect().height;
    
    // Menüyü sabitleme kontrolü
    if (kaymaMiktari > navbarYuksekligi) {
        navbar.classList.add("fixed-nav");
    } else {
        navbar.classList.remove("fixed-nav");
    }
    
    // Yukarı çık butonunu gösterme kontrolü
    if (kaymaMiktari > 500) {
        yukariButon.classList.add("show-link");
    } else {
        yukariButon.classList.remove("show-link");
    }
});

Proje 10: Tabs (Sekmeli İçerik Yapısı)

Mantık: Hangi sekmeye tıklanırsa altındaki yazı değişecek.

app.js

const sekmeler = document.querySelector(".about");
const butonlar = document.querySelectorAll(".tab-btn");
const icerikler = document.querySelectorAll(".content");

sekmeler.addEventListener("click", function(e) {
    const id = e.target.dataset.id;
    if (id) {
        // Diğer butonlardan aktif sınıfını kaldıralım
        butonlar.forEach(function(btn) {
            btn.classList.remove("active");
        });
        e.target.classList.add("active");
        
        // Tüm içerikleri gizleyip sadece eşleşeni açalım
        icerikler.forEach(function(makale) {
            makale.classList.remove("active");
        });
        const element = document.getElementById(id);
        element.classList.add("active");
    }
});

Proje 11: Countdown (Geri Sayım Sayacı)

Mantık: Hedef bir tarihten şu anki tarihi çıkartıp kalan zamanı milisaniye cinsinden bulacağız. Sonra bunu gün, saat, dakika ve saniyeye çevireceğiz.

app.js

const zamanKutulari = document.querySelectorAll(".deadline-format h4");

// Gelecekte bir hedef tarih belirleyelim (Örn: 10 gün sonrası)
let hedefTarih = new Date(2027, 5, 25, 11, 30, 0); 
const hedefMilisaniye = hedefTarih.getTime();

function kalanZamaniHesapla() {
    const suAnkiMilisaniye = new Date().getTime();
    const kalanZaman = hedefMilisaniye - suAnkiMilisaniye;
    
    // Zaman birimlerinin milisaniye karşılıkları
    const birGun = 24 * 60 * 60 * 1000;
    const birSaat = 60 * 60 * 1000;
    const birDakika = 60 * 1000;
    
    let gun = Math.floor(kalanZaman / birGun);
    let saat = Math.floor((kalanZaman % birGun) / birSaat);
    let dakika = Math.floor((kalanZaman % birSaat) / birDakika);
    let saniye = Math.floor((kalanZaman % birDakika) / 1000);
    
    const degerler = [gun, saat, dakika, saniye];
    
    zamanKutulari.forEach(function(kutu, indeks) {
        kutu.textContent = degerler[indeks];
    });
    
    if (kalanZaman < 0) {
        clearInterval(sayac);
        document.querySelector(".deadline").innerHTML = `<h4>Bu sürenin vadesi doldu!</h4>`;
    }
}

// Her saniye bu fonksiyonu tetikleyelim
let sayac = setInterval(kalanZamaniHesapla, 1000);
kalanZamaniHesapla();

Proje 12: Lorem Ipsum Generator (Rastgele Metin Üretici)

Mantık: Kullanıcı kaç adet paragraf isterse, elimizdeki listeden o kadar veriyi kesip ekrana basacağız.

app.js

const metinler = [
    "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
    "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
    "Ut enim ad minim veniam, quis nostrud exercitation ullamco."
];

const form = document.querySelector(".lorem-form");
const miktarInput = document.getElementById("amount");
const sonucAlani = document.querySelector(".lorem-text");

form.addEventListener("submit", function(e) {
    e.preventDefault(); // Sayfanın yenilenmesini engeller
    const deger = parseInt(miktarInput.value);
    
    // Girdi kontrolü yapalım
    if (isNaN(deger) || deger <= 0 || deger > metinler.length) {
        const rastgeleSira = Math.floor(Math.random() * metinler.length);
        sonucAlani.innerHTML = `<p class="result">${metinler[rastgeleSira]}</p>`;
    } else {
        let kesilenMetinler = metinler.slice(0, deger);
        kesilenMetinler = kesilenMetinler.map(item => `<p class="result">${item}</p>`).join("");
        sonucAlani.innerHTML = kesilenMetinler;
    }
});

Proje 13: Grocery Bud (Hafızalı Alışveriş Listesi)

Mantık: Eleman ekleyebileceğimiz, silebileceğimiz, güncelleyebileceğimiz ve sayfayı yenilesek bile Local Storage sayesinde kaybolmayacak tam teşekküllü bir CRUD (Ekle-Oku-Güncelle-Sil) uygulaması.

index.html

<section class="section-center">
    <form class="grocery-form">
        <p class="alert"></p>
        <h3>Alışveriş Listesi</h3>
        <div class="form-control">
            <input type="text" id="grocery" placeholder="Örn: Yumurta">
            <button type="submit" class="submit-btn">Ekle</button>
        </div>
    </form>
    <div class="grocery-container">
        <div class="grocery-list"></div>
        <button class="clear-btn">Listeyi Temizle</button>
    </div>
</section>

app.js

const form = document.querySelector(".grocery-form");
const alertYazisi = document.querySelector(".alert");
const sepetInput = document.getElementById("grocery");
const listeKonteyner = document.querySelector(".grocery-container");
const liste = document.querySelector(".grocery-list");
const temizleBtn = document.querySelector(".clear-btn");

let duzenlemeModu = false;
let duzenlenenEleman;
let duzenlemeID = "";

// Olay Yöneticileri
form.addEventListener("submit", elemanEkle);
temizleBtn.addEventListener("click", listeyiTemizle);
window.addEventListener("DOMContentLoaded", hafizadanYukle);

function elemanEkle(e) {
    e.preventDefault();
    const deger = sepetInput.value;
    const id = new Date().getTime().toString(); // Benzersiz ID üretme yolu
    
    if (deger && !duzenlemeModu) {
        htmlElemanOlustur(id, deger);
        alarmGoster("Eleman başarıyla eklendi", "success");
        listeKonteyner.classList.add("show-container");
        
        // Yerel hafızaya ekle
        hafizayaKaydet(id, deger);
        varsayılanaDon();
    } else if (deger && duzenlemeModu) {
        duzenlenenEleman.innerHTML = deger;
        alarmGoster("Değer değiştirildi", "success");
        hafizadaGuncelle(duzenlemeID, deger);
        varsayılanaDon();
    } else {
        alarmGoster("Lütfen bir değer giriniz!", "danger");
    }
}

function alarmGoster(metin, sinif) {
    alertYazisi.textContent = metin;
    alertYazisi.classList.add(`alert-${sinif}`);
    setTimeout(function() {
        alertYazisi.textContent = "";
        alertYazisi.classList.remove(`alert-${sinif}`);
    }, 2000);
}

function htmlElemanOlustur(id, deger) {
    const element = document.createElement("article");
    element.classList.add("grocery-item");
    const nitelik = document.createAttribute("data-id");
    nitelik.value = id;
    element.setAttributeNode(nitelik);
    
    element.innerHTML = `<p class="title">${deger}</p>
        <div class="btn-container">
            <button type="button" class="edit-btn">Düzenle</button>
            <button type="button" class="delete-btn">Sil</button>
        </div>`;
        
    // Silme ve Düzenleme butonlarını yakalayalım
    const silBtn = element.querySelector(".delete-btn");
    const duzenBtn = element.querySelector(".edit-btn");
    silBtn.addEventListener("click", elemanSil);
    duzenBtn.addEventListener("click", elemanDuzenle);
    
    liste.appendChild(element);
}

function elemanSil(e) {
    const element = e.currentTarget.parentElement.parentElement;
    const id = element.dataset.id;
    liste.removeChild(element);
    
    if (liste.children.length === 0) {
        listeKonteyner.classList.remove("show-container");
    }
    alarmGoster("Eleman silindi", "danger");
    hafizadanSil(id);
    varsayılanaDon();
}

function elemanDuzenle(e) {
    const element = e.currentTarget.parentElement.parentElement;
    duzenlenenEleman = e.currentTarget.parentElement.previousElementSibling;
    sepetInput.value = duzenlenenEleman.innerHTML;
    duzenlemeModu = true;
    duzenlemeID = element.dataset.id;
    document.querySelector(".submit-btn").textContent = "Düzenle";
}

function listeyiTemizle() {
    const elemanlar = document.querySelectorAll(".grocery-item");
    if (elemanlar.length > 0) {
        elemanlar.forEach(item => liste.removeChild(item));
    }
    listeKonteyner.classList.remove("show-container");
    alarmGoster("Liste temizlendi", "danger");
    localStorage.removeItem("groceryList");
    varsayılanaDon();
}

function varsayılanaDon() {
    sepetInput.value = "";
    duzenlemeModu = false;
    duzenlemeID = "";
    document.querySelector(".submit-btn").textContent = "Ekle";
}

// LOCAL STORAGE (HAFIZA) İŞLEMLERİ
function hafizayaKaydet(id, deger) {
    const grocery = { id: id, value: deger };
    let elemanlar = localStorage.getItem("groceryList") ? JSON.parse(localStorage.getItem("groceryList")) : [];
    elemanlar.push(grocery);
    localStorage.setItem("groceryList", JSON.stringify(elemanlar));
}

function hafizadanSil(id) {
    let elemanlar = JSON.parse(localStorage.getItem("groceryList"));
    elemanlar = elemanlar.filter(item => item.id !== id);
    localStorage.setItem("groceryList", JSON.stringify(elemanlar));
}

function hafizadaGuncelle(id, deger) {
    let elemanlar = JSON.parse(localStorage.getItem("groceryList"));
    elemanlar = elemanlar.map(function(item) {
        if (item.id === id) { item.value = deger; }
        return item;
    });
    localStorage.setItem("groceryList", JSON.stringify(elemanlar));
}

function hafizadanYukle() {
    let elemanlar = localStorage.getItem("groceryList") ? JSON.parse(localStorage.getItem("groceryList")) : [];
    if (elemanlar.length > 0) {
        elemanlar.forEach(item => htmlElemanOlustur(item.id, item.value));
        listeKonteyner.classList.add("show-container");
    }
}

Proje 14: Slider (Basit Görsel Kaydırıcı)

Mantık: Resimleri CSS ile yan yana dizeceğiz. Butona tıklandığında sola veya sağa doğru kaydıracağız.

app.js

const slaytlar = document.querySelectorAll(".slide");
const sonBtn = document.getElementById("nextBtn");
const ilkBtn = document.getElementById("prevBtn");

slaytlar.forEach(function(slayt, indeks) {
    slayt.style.left = `${indeks * 100}%`; // Resimleri yan yana dizer
});

let sayac = 0;
sonBtn.addEventListener("click", function() {
    sayac++;
    kaydir();
});
ilkBtn.addEventListener("click", function() {
    sayac--;
    kaydir();
});

function kaydir() {
    // Sınırları kontrol edelim
    if (sayac === slaytlar.length) { sayac = 0; }
    if (sayac < 0) { sayac = slaytlar.length - 1; }
    
    slaytlar.forEach(function(slayt) {
        slayt.style.transform = `translateX(-${sayac * 100}%)`;
    });
}

BÖLÜM 2: NESNE YÖNELİMLİ PROGRAMLAMA (OOP) PROJELERİ

Proje 15: Nesne Yönelimli Sayaç (Class Refactor)

Mantık: Sayfamızda birden çok bağımsız sayaç yapısını tek bir kalıpla (class) üreteceğiz.

app.js

class Sayac {
    constructor(element) {
        this.sayacAlani = element;
        this.deger = 0;
        this.artirBtn = element.querySelector(".artir");
        this.azaltBtn = element.querySelector(".azalt");
        this.degerYazisi = element.querySelector(".deger");
        
        // This bağlamını kilitleyelim
        this.artir = this.artir.bind(this);
        this.azalt = this.azalt.bind(this);
        
        this.artirBtn.addEventListener("click", this.artir);
        this.azaltBtn.addEventListener("click", this.azalt);
    }
    
    artir() {
        this.deger++;
        this.degerYazisi.textContent = this.deger;
    }
    
    azalt() {
        this.deger--;
        this.degerYazisi.textContent = this.deger;
    }
}

// Kullanımı: Sayfada iki farklı div varsa anında iki bağımsız sayaç olur
const birinciSayac = new Sayac(document.querySelector(".sayac-bir"));
const ikinciSayac = new Sayac(document.querySelector(".sayac-iki"));

Proje 16: Gelişmiş Resim Galerisi (OOP Galeri)

Mantık: Modüler bir yapıda, tıklandığında açılan büyük modal resim galerisi sınıfı tasarlayacağız.

app.js

class Galeri {
    constructor(element) {
        this.konteyner = element;
        this.liste = [...element.querySelectorAll(".img")];
        this.modal = document.querySelector(".modal");
        this.modalImg = document.querySelector(".main-img");
        this.kapatBtn = document.querySelector(".close-btn");
        
        this.konteyner.addEventListener("click", (e) => {
            if (e.target.classList.contains("img")) {
                this.modalAc(e.target);
            }
        });
    }
    
    modalAc(secilenResim) {
        this.modalImg.src = secilenResim.src;
        this.modal.classList.add("open");
        this.kapatBtn.addEventListener("click", () => this.modalKapat());
    }
    
    modalKapat() {
        this.modal.classList.remove("open");
    }
}

const mutfakGaleri = new Galeri(document.querySelector(".mutfak"));

BÖLÜM 3: MODERN JAVASCRIPT & ES6 PROJELERİ

Proje 17: Animasyonlu Sayılar (Numbers Efekti)

Mantık: Sayfa açılınca istatistik sayılarının sıfırdan hedef sayıya doğru hızla saymasını sağlayacağız.

app.js

const sayilar = document.querySelectorAll(".number");

const sayiGuncelle = (eleman) => {
    const hedefDeger = parseInt(eleman.dataset.value);
    const artisMiktari = Math.ceil(hedefDeger / 100);
    let baslangic = 0;
    
    const zamanlayici = setInterval(() => {
        baslangic += artisMiktari;
        if (baslangic >= hedefDeger) {
            eleman.textContent = `${hedefDeger}+`;
            clearInterval(zamanlayici);
            return;
        }
        eleman.textContent = `${baslangic}+`;
    }, 1);
};

sayilar.forEach(sayi => sayiGuncelle(sayi));

Proje 18: Dark Mode (Koyu Tema)

Mantık: Sitenin renk kodlarını CSS değişkenleriyle tanımlayacağız. Butona basılınca ana HTML etiketine .dark-theme sınıfı basarak tüm renkleri tersine çevireceğiz.

style.css

:root {
    --bg-color: white;
    --text-color: black;
}
.dark-theme {
    --bg-color: #222;
    --text-color: white;
}
body {
    background-color: var(--bg-color);
    color: var(--text-color);
}

app.js

const temaBtn = document.querySelector(".toggle-btn");

temaBtn.addEventListener("click", () => {
    document.documentElement.classList.toggle("dark-theme");
});

Proje 19: Canlı Ürün Filtreleme

Mantık: Arama çubuğuna harf yazıldıkça, ürün adlarıyla eşleşmeyen her şeyi anında ekrandan sileceğiz.

app.js

const urunler = [
    { isim: "Masa", marka: "Ikea" },
    { isim: "Sandalye", marka: "Vivense" }
];

const aramaInput = document.querySelector(".search-input");
const urunlerKutusu = document.querySelector(".products-container");

const urunleriGoster = (liste) => {
    urunlerKutusu.innerHTML = liste.map(u => `<h6>${u.isim} - ${u.marka}</h6>`).join("");
};

aramaInput.addEventListener("keyup", () => {
    const arananKelime = aramaInput.value.toLowerCase();
    const suzulenler = urunler.filter(u => u.isim.toLowerCase().includes(arananKelime));
    urunleriGoster(suzulenler);
});

// İlk açılışta hepsini göster
urunleriGoster(urunler);

BÖLÜM 4: ASENKRON JAVASCRIPT & API PROJELERİ

Proje 20: Dad Jokes (Rastgele Espri Getirici)

Mantık: İnternetteki canlı bir espri sunucusuna (API) asenkron bağlanıp, gelen veriyi yakalayacağız.

app.js

const url = "https://icanhazdadjoke.com";
const btn = document.querySelector(".btn");
const sonucYazisi = document.querySelector(".result");

const espriGetir = async () => {
    sonucYazisi.textContent = "Yükleniyor...";
    try {
        // API kuralları gereği Header (başlık) bilgisi ekliyoruz
        const cevap = await fetch(url, {
            headers: { Accept: "application/json" }
        });
        const veri = await cevap.json();
        sonucYazisi.textContent = veri.joke;
    } catch (hata) {
        sonucYazisi.textContent = "Bir hata oluştu!";
    }
};

btn.addEventListener("click", espriGetir);
espriGetir();

Proje 21: Canlı Ürün Listesi ve Detay Sayfası

Mantık: API'den gelen verileri ana sayfada listeleyeceğiz. Bir ürüne tıklanınca tarayıcı adres satırına ID parametresi (detay.html?id=123) ekleyerek detay sayfasına yönlendireceğiz.

ana-sayfa.js

const urunlerUrl = "https://course-api.com";
const konteyner = document.querySelector(".products-container");

const urunleriCek = async () => {
    const cevap = await fetch(urunlerUrl);
    const veriler = await cevap.json();
    
    konteyner.innerHTML = veriler.map(urun => {
        const { id } = urun;
        const { name, price } = urun.fields;
        const resim = urun.fields.image[0].url;
        
        return `<a href="detay.html?id=${id}">
            <img src="${resim}">
            <footer><h5>${name}</h5><span>${price/100} TL</span></footer>
        </a>`;
    }).join("");
};
urunleriCek();

detay.js

// URL'deki ?id=... kısmını okuma yöntemi
const urlParametreleri = new URLSearchParams(window.location.search);
const urunID = urlParametreleri.get("id");

const tekUrunUrl = `https://course-api.com{urunID}`;

const urunDetayiniGoster = async () => {
    const cevap = await fetch(tekUrunUrl);
    const veri = await cevap.json();
    
    const { name, description } = veri.fields;
    document.querySelector(".title").textContent = name;
    document.querySelector(".desc").textContent = description;
};
urunDetayiniGoster();

Proje 22: Cocktails (Gelişmiş Kokteyl Ansiklopedisi)

Mantık: Arama çubuğuna yazılan içecek adını dinamik olarak API URL'sine ekleyip (://cocktaildb.com) canlı sonuç getireceğiz.

app.js

const url = "https://thecocktaildb.com";
const form = document.querySelector(".search-form");
const girdi = document.querySelector("[name='drink']");
const liste = document.querySelector(".drinks-center");

const kokteylleriYukle = async (aranan) => {
    liste.innerHTML = "<h2>Yükleniyor...</h2>";
    const cevap = await fetch(`${url}${aranan}`);
    const veri = await cevap.json();
    
    if (!veri.drinks) {
        liste.innerHTML = "<h2>Aradığınız içecek bulunamadı!</h2>";
        return;
    }
    
    liste.innerHTML = veri.drinks.map(ic => {
        return `<article>
            <img src="${ic.strDrinkThumb}">
            <h3>${ic.strDrink}</h3>
        </article>`;
    }).join("");
};

form.addEventListener("keyup", () => {
    kokteylleriYukle(girdi.value);
});
kokteylleriYukle("a"); // İlk açılışta 'a' harfi içerenleri getirir

BÖLÜM 5: İLERİ DÜZEY KOMPLEKS UYGULAMALAR

Proje 23: Stripe Tarzı Akıllı Alt Menü (Submenus)

Mantık: Fare hangi butonun üstüne gelirse, alt menü kutusu (getBoundingClientRect) ile o butonun altına otomatik kayıp genişleyecek.

app.js

const linkButonlari = [...document.querySelectorAll(".link-btn")];
const altMenu = document.querySelector(".submenu");

linkButonlari.forEach(btn => {
    btn.addEventListener("mouseover", function(e) {
        const butonKonumu = e.currentTarget.getBoundingClientRect();
        const ortaNokta = (butonKonumu.left + butonKonumu.right) / 2;
        const altNokta = butonKonumu.bottom - 3;
        
        altMenu.style.left = `${ortaNokta}px`;
        altMenu.style.top = `${altNokta}px`;
        altMenu.classList.add("show"); // Menüyü görünür yapar
    });
});

Proje 24: Pagination (Canlı Sayfalama Sistemi)

Mantık: API'den gelen 100 adet büyük veriyi matematiksel formülle (slice) sayfa başına 10'arlı gruplara bölüp dinamik sayfalar üreteceğiz.

app.js

const url = "https://github.com";
let sayfadakiVeriler = [];
let aktifSayfa = 0;

const sayfalariOlustur = (takipciler) => {
    const sayfaBasiEleman = 10;
    const toplamSayfaSayisi = Math.ceil(takipciler.length / sayfaBasiEleman);
    
    // Büyük diziyi küçük parçalara ayıralım
    const yeniDizi = Array.from({ length: toplamSayfaSayisi }, (_, indeks) => {
        const baslangic = indeks * sayfaBasiEleman;
        return takipciler.slice(baslangic, baslangic + sayfaBasiEleman);
    });
    return yeniDizi;
};

const ekranaBas = () => {
    const aktifGrup = sayfadakiVeriler[aktifSayfa];
    document.querySelector(".container").innerHTML = aktifGrup.map(t => `<h4>${t.login}</h4>`).join("");
    ButonlariGoster();
};

const ButonlariGoster = () => {
    let btnHtml = sayfadakiVeriler.map((_, sira) => {
        return `<button class="page-btn ${sira === aktifSayfa ? 'active' : ''}" data-index="${sira}">${sira + 1}</button>`;
    }).join("");
    document.querySelector(".btn-container").innerHTML = btnHtml;
};

document.querySelector(".btn-container").addEventListener("click", (e) => {
    if (e.target.classList.contains("page-btn")) {
        aktifSayfa = parseInt(e.target.dataset.index);
        ekranaBas();
    }
});

const baslat = async () => {
    const cevap = await fetch(url);
    const veriler = await cevap.json();
    sayfadakiVeriler = sayfalariOlustur(veriler);
    ekranaBas();
};
baslat();

Proje 25: Comfy Mağazası (Dev E-Ticaret Sistemi Mimarisi)

Mantık: Kursun en büyük projesidir. Modüler mimariyle sepet yönetimini, fiyat toplamlarını ve çoklu filtreleri (Kelime + Fiyat Çubuğu + Marka) tek elden kontrol edeceğiz.

app.js

// Merkezi Depo (State)
let sepet = [];
let urun Deposu = [];

const urunleriUzaktenCek = async () => {
    const cevap = await fetch("https://course-api.com");
    urunDeposu = await cevap.json();
    magazayiOlustur(urunDeposu);
};

// 1. Mağaza Kartlarını Üretme
function magazayiOlustur(listelenenUrunler) {
    const alan = document.querySelector(".products-container");
    alan.innerHTML = listelenenUrunler.map(u => {
        return `<article class="product">
            <img src="${u.fields.image[0].url}">
            <h4>${u.fields.name}</h4>
            <p>${u.fields.price / 100} TL</p>
            <button class="add-to-cart" data-id="${u.id}">Sepete Ekle</button>
        </article>`;
    }).join("");
    
    // Sepete ekleme butonlarını dinleyelim
    alan.querySelectorAll(".add-to-cart").forEach(btn => {
        btn.addEventListener("click", sepetElemanEkle);
    });
}

// 2. Sepet Mantığı
function sepetElemanEkle(e) {
    const id = e.target.dataset.id;
    const sepette VarMi = sepet.find(item => item.id === id);
    
    if (sepetteVarMi) {
        sepetteVarMi.miktar++;
    } else {
        const urun = urunDeposu.find(item => item.id === id);
        sepet.push({ id: urun.id, isim: urun.fields.name, fiyat: urun.fields.price, miktar: 1 });
    }
    sepetiGuncelle();
}

function sepetiGuncelle() {
    // Toplam Fiyat ve Adet Hesaplama (Reduce ile)
    const sepetOzeti = sepet.reduce((toplam, item) => {
        toplam.para += item.fiyat * item.miktar;
        toplam.adet += item.miktar;
        return toplam;
    }, { para: 0, adet: 0 });
    
    document.querySelector(".cart-total").textContent = `${sepetOzeti.para / 100} TL`;
    document.querySelector(".cart-items-count").textContent = sepetOzeti.adet;
    
    // Hafızayı koru
    localStorage.setItem("comfySepet", JSON.stringify(sepet));
}

// 3. Çoklu Fiyat ve Filtre Çubuğu Kontrolü
const fiyatCubugu = document.querySelector(".price-filter");
fiyatCubugu.addEventListener("input", () => {
    const maxFiyat = fiyatCubugu.value;
    const filtrelenmis = urunDeposu.filter(u => (u.fields.price / 100) <= maxFiyat);
    magazayiOlustur(filtrelenmis);
});

// Başlangıç Ayarları
window.addEventListener("DOMContentLoaded", () => {
    sepet = localStorage.getItem("comfySepet") ? JSON.parse(localStorage.getItem("comfySepet")) : [];
    urunleriUzaktenCek();
    sepetiGuncelle();
});

Projeleri Nasıl Çalıştıracaksınız?

  1. Bilgisayarınızda bir klasör oluşturun (Örn: JavaScriptProjeleri).

  2. İçine her uygulama için yeni bir klasör açın (renk-degistirici, alisveris-sepeti vb.).

  3. İlgili kodları index.html, style.css ve app.js isimleriyle kaydedip kod editörünüzdeki (VS Code) Live Preview veya Live Server butonuna basarak tarayıcıda canlı olarak test edin.

==============================================================================================

Müfredatta yer alan tüm temel, orta ve ileri düzey projelerin arayüzlerini modern standartlara taşımak için gelişmiş CSS mimarileri (CSS Variables, Flexbox, Grid, Glassmorphism ve gelişmiş animasyonlar) ekledim.

Tasarımların birbirini bozmaması için her projenin HTML, CSS ve JavaScript kodlarını kendi içinde tam uyumlu ve eksiksiz olacak şekilde baştan aşağı yeniledim.


BÖLÜM 1: TEMEL DOM PROJELERİ

Proje 1: Color Flipper (Glassmorphism Arayüzü)

Tasarım Detayı: Arka plana uyum sağlayan, yarı saydam ve arkasını bulandıran modern bir cam efekti (Glassmorphism) kart tasarımı eklenmiştir.

index.html

<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Modern Renk Değiştirici</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="glass-card">
        <h2>Arka Plan Rengi: <span id="color-code">#6366F1</span></h2>
        <button id="flip-btn">Rengi Rastgele Değiştir</button>
    </div>
    <script src="app.js"></script>
</body>
</html>

style.css

:root {
    --transition-speed: 0.4s;
}

body {
    font-family: 'Segoe UI', system-ui, sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background: linear-gradient(135deg, #6366f1, #a855f7);
    transition: background var(--transition-speed) ease;
}

.glass-card {
    background: rgba(255, 255, 255, 0.2);
    backdrop-filter: blur(15px);
    -webkit-backdrop-filter: blur(15px);
    border: 1px solid rgba(255, 255, 255, 0.3);
    padding: 2.5rem;
    border-radius: 20px;
    box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.2);
    text-align: center;
    color: #ffffff;
}

h2 {
    margin-bottom: 2rem;
    font-size: 1.8rem;
    letter-spacing: 1px;
}

#color-code {
    background: rgba(0, 0, 0, 0.3);
    padding: 0.3rem 0.8rem;
    border-radius: 8px;
    font-family: monospace;
    font-weight: bold;
}

button {
    background: #ffffff;
    color: #4f46e5;
    border: none;
    padding: 0.8rem 1.8rem;
    font-size: 1rem;
    font-weight: 600;
    border-radius: 10px;
    cursor: pointer;
    transition: all 0.3s ease;
    box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}

button:hover {
    transform: translateY(-3px);
    box-shadow: 0 6px 20px rgba(0,0,0,0.2);
    background: #f3f4f6;
}

button:active {
    transform: translateY(-1px);
}

app.js

const hex = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F"];
const btn = document.getElementById("flip-btn");
const color = document.getElementById("color-code");

btn.addEventListener("click", () => {
    let hexColor = "#";
    for (let i = 0; i < 6; i++) {
        hexColor += hex[Math.floor(Math.random() * hex.length)];
    }
    color.textContent = hexColor;
    document.body.style.background = hexColor;
});

Proje 2: Counter (Neumorphism Tarzı Sayaç)

Tasarım Detayı: Butonlara ve ana ekrana yumuşak gölgelerle gömülme ve kabarma hissi veren Neumorphic tasarım dili uygulanmıştır.

index.html

<div class="neumorphic-counter">
    <div class="display-box">
        <h1 id="value">0</h1>
    </div>
    <div class="btn-group">
        <button class="control-btn decrease">Azalt</button>
        <button class="control-btn reset">Sifirla</button>
        <button class="control-btn increase">Artir</button>
    </div>
</div>

style.css

body {
    background-color: #e0e0e0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    font-family: 'Segoe UI', sans-serif;
}

.neumorphic-counter {
    background: #e0e0e0;
    padding: 3rem;
    border-radius: 30px;
    box-shadow: 15px 15px 30px #bebebe, -15px 15px 30px #ffffff;
    text-align: center;
}

.display-box {
    background: #e0e0e0;
    padding: 1.5rem;
    border-radius: 20px;
    box-shadow: inset 7px 7px 14px #bebebe, inset -7px -7px 14px #ffffff;
    margin-bottom: 2rem;
}

#value {
    font-size: 4rem;
    margin: 0;
    color: #333;
    transition: color 0.3s ease;
}

.btn-group {
    display: flex;
    gap: 1rem;
}

.control-btn {
    border: none;
    background: #e0e0e0;
    padding: 1rem 1.5rem;
    font-size: 1rem;
    font-weight: 600;
    border-radius: 12px;
    cursor: pointer;
    color: #666;
    box-shadow: 5px 5px 10px #bebebe, -5px -5px 10px #ffffff;
    transition: all 0.2s ease;
}

.control-btn:hover {
    color: #333;
}

.control-btn:active {
    box-shadow: inset 3px 3px 6px #bebebe, inset -3px -3px 6px #ffffff;
}

app.js

let count = 0;
const value = document.getElementById("value");
const btns = document.querySelectorAll(".control-btn");

btns.forEach((btn) => {
    btn.addEventListener("click", (e) => {
        const styles = e.currentTarget.classList;
        if (styles.contains("decrease")) {
            count--;
        } else if (styles.contains("increase")) {
            count++;
        } else {
            count = 0;
        }

        if (count > 0) value.style.color = "#10B981";
        if (count < 0) value.style.color = "#EF4444";
        if (count === 0) value.style.color = "#333333";
        
        value.textContent = count;
    });
});

Proje 3: Reviews (Profil Kartı Animasyonu)

Tasarım Detayı: Yuvarlatılmış profil resmi, şık tırnak işaretleri arka planı ve pürüzsüz geçiş sağlayan buton animasyonları eklenmiştir.

style.css

body {
    background-color: #f1f5f9;
    font-family: sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
}

.review-card {
    background: #ffffff;
    padding: 2.5rem;
    border-radius: 16px;
    box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
    max-width: 500px;
    width: 90%;
    text-align: center;
    position: relative;
}

.img-container {
    width: 120px;
    height: 120px;
    border-radius: 50%;
    margin: 0 auto 1.5rem;
    position: relative;
    background: #10b981;
}

.img-container img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
    position: relative;
    z-index: 1;
}

.img-container::before {
    content: '';
    position: absolute;
    top: -4px;
    right: -4px;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: #6366f1;
}

#author {
    margin: 0;
    font-size: 1.25rem;
    color: #1e293b;
}

#job {
    text-transform: uppercase;
    color: #6366f1;
    font-size: 0.85rem;
    font-weight: 600;
    margin-bottom: 1rem;
    display: inline-block;
}

#info {
    color: #64748b;
    line-height: 1.6;
}

.nav-container {
    margin-top: 1.5rem;
}

.nav-btn {
    background: none;
    border: none;
    font-size: 1.5rem;
    color: #6366f1;
    cursor: pointer;
    margin: 0 0.5rem;
    transition: color 0.2s;
}

.nav-btn:hover {
    color: #4f46e5;
}

Proje 4: Navbar & Sidebar (Akışkan Mobil Menü)

Tasarım Detayı: Sol taraftan kayarak gelen, gölgelendirmeli ve ekranı karartan arka plan kaplamalı (overlay) mobil uyumlu tasarım.

style.css

.sidebar {
    position: fixed;
    top: 0;
    left: 0;
    width: 300px;
    height: 100%;
    background: #ffffff;
    box-shadow: 5px 0 25px rgba(0,0,0,0.1);
    transform: translateX(-100%);
    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    z-index: 999;
    padding: 2rem;
}

.show-sidebar {
    transform: translateX(0);
}

.sidebar-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid #f1f5f9;
    padding-bottom: 1rem;
}

.close-btn {
    font-size: 2rem;
    background: transparent;
    border: none;
    color: #ef4444;
    cursor: pointer;
}

.links a {
    display: block;
    padding: 1rem;
    color: #334155;
    text-decoration: none;
    font-size: 1.1rem;
    border-radius: 8px;
    transition: background 0.2s;
}

.links a:hover {
    background: #f8fafc;
    color: #6366f1;
}

Proje 5: Modal (Fade-in Zoom Efekti)

Tasarım Detayı: Arka planı karartıp, modal penceresini yukarıdan aşağıya doğru ölçeklenerek (transform: scale) getiren pürüzsüz animasyon.

style.css

.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(15, 23, 42, 0.6);
    display: grid;
    place-items: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
    z-index: 1000;
}

.open-modal {
    opacity: 1;
    pointer-events: auto;
}

.modal-container {
    background: #ffffff;
    padding: 3rem;
    border-radius: 16px;
    max-width: 500px;
    width: 90%;
    text-align: center;
    position: relative;
    transform: translateY(-30px) scale(0.9);
    transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.open-modal .modal-container {
    transform: translateY(0) scale(1);
}

Proje 6: Questions (Modern Akordeon Kartları)

Tasarım Detayı: Soruların ve cevapların yumuşak yükseklik geçişi ve aktif kartın kenar çizgisi renginin değişmesi sağlandı.

style.css

.question {
    background: #ffffff;
    border: 2px solid #e2e8f0;
    border-radius: 12px;
    padding: 1.5rem;
    margin-bottom: 1rem;
    transition: all 0.3s ease;
}

.question.show-text {
    border-color: #6366f1;
    box-shadow: 0 4px 20px rgba(99, 102, 241, 0.1);
}

.question-title {
    display: flex;
    justify-content: space-between;
    align-items: center;
    cursor: pointer;
}

.question-text {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease-out;
    color: #475569;
    line-height: 1.6;
}

.question.show-text .question-text {
    max-height: 200px;
    margin-top: 1rem;
    border-top: 1px solid #f1f5f9;
    padding-top: 1rem;
}

Proje 7: Restoran Menüsü (Gelişmiş Grid Grid ve Filtreler)

Tasarım Detayı: CSS Grid mimarisi ile duyarlı (responsive) kart dizilimi ve kategori butonlarına özel aktif durum efektleri eklendi.

style.css

.btn-container {
    display: flex;
    justify-content: center;
    gap: 1rem;
    margin-bottom: 3rem;
}

.filter-btn {
    background: transparent;
    border: 2px solid #6366f1;
    color: #6366f1;
    padding: 0.5rem 1.2rem;
    border-radius: 30px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s;
}

.filter-btn:hover, .filter-btn.active {
    background: #6366f1;
    color: #ffffff;
}

.section-center {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
    gap: 2rem;
    width: 90vw;
    max-width: 1170px;
    margin: 0 auto;
}

.menu-item {
    background: #ffffff;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 4px 6px -1px rgba(0,0,0,0.05);
}

.item-info {
    padding: 1.5rem;
}

header {
    display: flex;
    justify-content: space-between;
    border-bottom: 0.5px dashed #cbd5e1;
    padding-bottom: 0.5rem;
    margin-bottom: 1rem;
}

.price {
    color: #6366f1;
}

Proje 8: Video Kontrolü ve Yükleme Ekranı (Preloader)

Tasarım Detayı: Tam ekran arka plan videosu katmanı, kaydırmalı buton tasarımı (toggle switch) ve dönen yükleme halkası animasyonu.

style.css

.preloader {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: #ffffff;
    z-index: 9999;
    display: grid;
    place-items: center;
    transition: opacity 0.3s;
}

.hide-preloader {
    opacity: 0;
    pointer-events: none;
}

.spinner {
    width: 50px;
    height: 50px;
    border: 5px solid #e2e8f0;
    border-top-color: #6366f1;
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

.switch-btn {
    position: absolute;
    bottom: 7%; left: 7%;
    width: 7rem; height: 2.5rem;
    background: #6366f1;
    border-radius: 30px;
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 0.5rem;
}

.switch-btn span {
    color: #fff; font-size: 0.8rem; font-weight: bold;
}

.switch-style {
    position: absolute;
    top: 0; left: 0;
    width: 50%; height: 100%;
    background: #ffffff;
    border-radius: 30px;
    transition: transform 0.2s linear;
}

.slide .switch-style {
    transform: translateX(100%);
}

Proje 9: Scroll (Sticky Navbar & Smooth Scroll)

Tasarım Detayı: Sayfa aşağı indikçe camlaşan (blur) ve daralan yapışkan menü (sticky navbar) tasarımı.

style.css

nav {
    position: absolute;
    top: 0; left: 0; width: 100%;
    padding: 1.5rem 0;
    transition: all 0.3s ease;
    z-index: 100;
}

.fixed-nav {
    position: fixed;
    background: rgba(255, 255, 255, 0.8);
    backdrop-filter: blur(10px);
    padding: 0.8rem 0;
    box-shadow: 0 4px 20px rgba(0,0,0,0.05);
}

.top-link {
    position: fixed;
    bottom: 2rem; right: -5rem;
    background: #6366f1;
    color: white;
    width: 3rem; height: 3rem;
    border-radius: 50%;
    display: grid;
    place-items: center;
    transition: all 0.3s ease;
}

.show-link {
    right: 2rem;
}

Proje 10: Tabs (Sekmeli İçerik Kart Tasarımı)

Tasarım Detayı: Sekmeler arası geçişlerde solma ve aktif tab çizgisinin vurgulanması sağlandı.

style.css

.tab-btn {
    padding: 1rem 2rem;
    border: none;
    background: #f8fafc;
    cursor: pointer;
    font-size: 1rem;
    font-weight: 600;
    color: #64748b;
    border-bottom: 2px solid transparent;
    transition: all 0.2s;
}

.tab-btn.active {
    background: #ffffff;
    color: #6366f1;
    border-bottom-color: #6366f1;
}

.content {
    display: none;
    padding: 2rem;
    background: #ffffff;
    animation: fadeIn 0.4s ease;
}

.content.active {
    display: block;
}

@keyframes fadeIn {
    from { opacity: 0; transform: translateY(5px); }
    to { opacity: 1; transform: translateY(0); }
}

Proje 11: Countdown (Lüks Sayaç Kutuları)

Tasarım Detayı: Koyu gri neon detaylı kartlar ile zaman birimlerinin modern kutular içinde gösterimi.

style.css

.countdown-container {
    display: flex;
    gap: 1.5rem;
    justify-content: center;
    margin-top: 2rem;
}

.deadline-format {
    background: #1e293b;
    color: #ffffff;
    padding: 1.5rem;
    border-radius: 16px;
    width: 90px;
    text-align: center;
    box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1);
}

.deadline-format h4 {
    font-size: 2.5rem;
    margin: 0;
    color: #38bdf8;
    font-family: monospace;
}

.deadline-format span {
    font-size: 0.8rem;
    text-transform: uppercase;
    color: #94a3b8;
    letter-spacing: 1px;
}

Proje 12: Lorem Ipsum Generator (Minimalist Form Düzeni)

Tasarım Detayı: Temiz girdi (input) alanı, animasyonlu form butonu ve gölgeli paragraf çıktı blokları.

style.css

.lorem-form {
    display: flex;
    gap: 1rem;
    justify-content: center;
    align-items: center;
}

input[type="number"] {
    padding: 0.75rem;
    border: 2px solid #cbd5e1;
    border-radius: 8px;
    width: 80px;
    font-size: 1rem;
}

input[type="number"]:focus {
    outline: none;
    border-color: #6366f1;
}

.result p {
    background: #ffffff;
    padding: 1.5rem;
    border-radius: 12px;
    margin-bottom: 1rem;
    box-shadow: 0 2px 4px rgba(0,0,0,0.02);
    border-left: 4px solid #6366f1;
}

Proje 13: Grocery Bud (Premium Yapılacaklar Listesi)

Tasarım Detayı: Listeye eklenen elemanların sağa doğru kayarak gelmesi ve silerken solması için gelişmiş liste animasyonları ve şık buton tasarımları.

index.html

<section class="grocery-app">
    <form class="grocery-form">
        <p class="alert"></p>
        <h3>Mutfak Alisverisi</h3>
        <div class="input-group">
            <input type="text" id="grocery" placeholder="Örn: Süt al...">
            <button type="submit" class="submit-btn">Ekle</button>
        </div>
    </form>
    <div class="grocery-container">
        <div class="grocery-list"></div>
        <button class="clear-btn">Listeyi Temizle</button>
    </div>
</section>

style.css

body {
    background-color: #f8fafc;
    font-family: 'Segoe UI', sans-serif;
    display: grid;
    place-items: center;
    height: 100vh;
    margin: 0;
}

.grocery-app {
    background: #ffffff;
    padding: 2.5rem;
    border-radius: 20px;
    box-shadow: 0 20px 25px -5px rgba(0,0,0,0.05);
    width: 90vw;
    max-width: 450px;
}

.input-group {
    display: flex;
    gap: 0.5rem;
}

#grocery {
    flex: 1;
    padding: 0.8rem 1rem;
    border: 2px solid #e2e8f0;
    border-radius: 10px;
    font-size: 1rem;
    transition: border-color 0.2s;
}

#grocery:focus {
    outline: none;
    border-color: #6366f1;
}

.submit-btn {
    background: #6366f1;
    color: white;
    border: none;
    padding: 0 1.5rem;
    border-radius: 10px;
    font-weight: 600;
    cursor: pointer;
}

.grocery-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.75rem 1rem;
    background: #f8fafc;
    margin-top: 1rem;
    border-radius: 8px;
    animation: slideIn 0.3s ease;
}

@keyframes slideIn {
    from { opacity: 0; transform: translateX(-10px); }
    to { opacity: 1; transform: translateX(0); }
}

.alert {
    padding: 0.5rem;
    border-radius: 6px;
    text-align: center;
    font-size: 0.9rem;
    font-weight: 500;
}

.alert-success { background: #dcfce7; color: #15803d; }
.alert-danger { background: #fee2e2; color: #b91c1c; }

app.js

const form = document.querySelector(".grocery-form");
const alertYazisi = document.querySelector(".alert");
const sepetInput = document.getElementById("grocery");
const listeKonteyner = document.querySelector(".grocery-container");
const liste = document.querySelector(".grocery-list");
const temizleBtn = document.querySelector(".clear-btn");

let duzenlemeModu = false;
let duzenlenenEleman;
let duzenlemeID = "";

form.addEventListener("submit", elemanEkle);
temizleBtn.addEventListener("click", listeyiTemizle);
window.addEventListener("DOMContentLoaded", hafizadanYukle);

function elemanEkle(e) {
    e.preventDefault();
    const deger = sepetInput.value;
    const id = new Date().getTime().toString();
    
    if (deger && !duzenlemeModu) {
        htmlElemanOlustur(id, deger);
        alarmGoster("Eleman basariyla eklendi", "success");
        listeKonteyner.classList.add("show-container");
        hafizayaKaydet(id, deger);
        varsayılanaDon();
    } else if (deger && duzenlemeModu) {
        duzenlenenEleman.innerHTML = deger;
        alarmGoster("Deger degistirildi", "success");
        hafizadaGuncelle(duzenlemeID, deger);
        varsayılanaDon();
    } else {
        alarmGoster("Lütfen bir deger giriniz!", "danger");
    }
}

function alarmGoster(metin, sinif) {
    alertYazisi.textContent = metin;
    alertYazisi.className = `alert alert-${sinif}`;
    setTimeout(() => {
        alertYazisi.textContent = "";
        alertYazisi.className = "alert";
    }, 2000);
}

function htmlElemanOlustur(id, deger) {
    const element = document.createElement("article");
    element.classList.add("grocery-item");
    element.setAttribute("data-id", id);
    
    element.innerHTML = `<p class="title">${deger}</p>
        <div class="btn-group">
            <button type="button" class="edit-btn" style="color: #6366f1; border:none; background:none; cursor:pointer;">Duzenle</button>
            <button type="button" class="delete-btn" style="color: #ef4444; border:none; background:none; cursor:pointer; margin-left:10px;">Sil</button>
        </div>`;
        
    element.querySelector(".delete-btn").addEventListener("click", elemanSil);
    element.querySelector(".edit-btn").addEventListener("click", elemanDuzenle);
    liste.appendChild(element);
}

function elemanSil(e) {
    const element = e.currentTarget.parentElement.parentElement;
    const id = element.dataset.id;
    liste.removeChild(element);
    if (liste.children.length === 0) listeKonteyner.classList.remove("show-container");
    alarmGoster("Eleman silindi", "danger");
    hafizadanSil(id);
    varsayılanaDon();
}

function elemanDuzenle(e) {
    const element = e.currentTarget.parentElement.parentElement;
    duzenlenenEleman = e.currentTarget.parentElement.previousElementSibling;
    sepetInput.value = duzenlenenEleman.innerHTML;
    duzenlemeModu = true;
    duzenlemeID = element.dataset.id;
    form.querySelector(".submit-btn").textContent = "Duzenle";
}

function listeyiTemizle() {
    const elemanlar = document.querySelectorAll(".grocery-item");
    if (elemanlar.length > 0) elemanlar.forEach(item => liste.removeChild(item));
    listeKonteyner.classList.remove("show-container");
    alarmGoster("Liste temizlendi", "danger");
    localStorage.removeItem("groceryList");
    varsayılanaDon();
}

function varsayılanaDon() {
    sepetInput.value = "";
    duzenlemeModu = false;
    duzenlemeID = "";
    form.querySelector(".submit-btn").textContent = "Ekle";
}

function hafizayaKaydet(id, deger) {
    let elemanlar = localStorage.getItem("groceryList") ? JSON.parse(localStorage.getItem("groceryList")) : [];
    elemanlar.push({ id, value: deger });
    localStorage.setItem("groceryList", JSON.stringify(elemanlar));
}

function hafizadanSil(id) {
    let elemanlar = JSON.parse(localStorage.getItem("groceryList"));
    elemanlar = elemanlar.filter(item => item.id !== id);
    localStorage.setItem("groceryList", JSON.stringify(elemanlar));
}

function hafizadaGuncelle(id, deger) {
    let elemanlar = JSON.parse(localStorage.getItem("groceryList"));
    elemanlar = elemanlar.map(item => {
        if (item.id === id) item.value = deger;
        return item;
    });
    localStorage.setItem("groceryList", JSON.stringify(elemanlar));
}

function hafizadanYukle() {
    let elemanlar = localStorage.getItem("groceryList") ? JSON.parse(localStorage.getItem("groceryList")) : [];
    if (elemanlar.length > 0) {
        elemanlar.forEach(item => htmlElemanOlustur(item.id, item.value));
        listeKonteyner.classList.add("show-container");
    }
}

Proje 14: Slider (Full-screen Kenarlıksız Slayt)

Tasarım Detayı: Ekranı kaplayan, yumuşak kayma efektine sahip ok butonlu minimalist galeri geçişi.

style.css

.slider-container {
    position: relative;
    width: 80vw; height: 50vh;
    margin: 0 auto;
    overflow: hidden;
    border-radius: 16px;
    box-shadow: 0 20px 25px -5px rgba(0,0,0,0.1);
}

.slide {
    position: absolute;
    width: 100%; height: 100%;
    transition: transform 0.5s cubic-bezier(0.77, 0, 0.175, 1);
}

.btn-container {
    position: absolute;
    top: 50%; transform: translateY(-50%);
    width: 100%; display: flex;
    justify-content: space-between;
    padding: 0 1rem; box-sizing: border-box;
    z-index: 10;
}

BÖLÜM 2: NESNE YÖNELİMLİ PROGRAMLAMA (OOP) PROJELERİ

Proje 15: Nesne Yönelimli Sayaç (Çoklu Kart Tasarımı)

Tasarım Detayı: Sayfada yan yana duran, bağımsız renk temalarına sahip dinamik sayaç kart mimarisi.

style.css

.sayac-kart {
    background: #ffffff;
    border-radius: 16px;
    padding: 2rem;
    box-shadow: 0 10px 15px -3px rgba(0,0,0,0.05);
    text-align: center;
    width: 200px;
}

.deger {
    font-size: 3rem;
    font-weight: 800;
    margin: 1rem 0;
}

Proje 16: Gelişmiş Resim Galerisi (Masonry Grid & Lightbox)

Tasarım Detayı: Resimlerin üzerine gelindiğinde parlayan, tıklandığında ekranı kaplayan koyu temalı premium Lightbox modal penceresi.

style.css

.gallery-center {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 1.5rem;
    padding: 2rem;
}

.img {
    width: 100%; height: 200px;
    object-fit: cover;
    border-radius: 12px;
    cursor: pointer;
    transition: transform 0.3s, filter 0.3s;
}

.img:hover {
    transform: scale(1.03);
    filter: brightness(0.9);
}

.modal.open {
    display: grid;
    place-items: center;
    position: fixed;
    top: 0; left: 0; width: 100%; height: 100%;
    background: rgba(0,0,0,0.9);
    z-index: 10000;
}

BÖLÜM 3: MODERN JAVASCRIPT & ES6 PROJELERİ

Proje 17: Animasyonlu Sayılar (Dashboard Sayaç Kutuları)

Tasarım Detayı: Modern veri analiz panellerindeki (dashboard) gibi parlayan neon yeşil istatistik sayıları.

style.css

.number-card {
    background: #0f172a;
    border: 1px solid #1e293b;
    padding: 2.5rem;
    border-radius: 16px;
    text-align: center;
    min-width: 180px;
}

.number {
    font-size: 3.5rem;
    color: #10b981;
    font-weight: bold;
    text-shadow: 0 0 20px rgba(16, 185, 129, 0.4);
}

Proje 18: Dark Mode (Kapsamlı Gece Teması)

Tasarım Detayı: Sadece arka planı değil, kart gölgelerini ve yazı renklerini gözü yormayacak derin gri tona çeken sistem.

style.css

:root {
    --bg: #f8fafc;
    --card: #ffffff;
    --text: #0f172a;
}

.dark-theme {
    --bg: #0f172a;
    --card: #1e293b;
    --text: #f8fafc;
}

body { background: var(--bg); color: var(--text); transition: all 0.3s; }
.card { background: var(--card); }

Proje 19: Canlı Ürün Filtreleme (Arama Alanı & Badge Sistemi)

Tasarım Detayı: Filtrelenen ürün sayılarını ve markaları şık rozetlerle (badge) gösteren temiz liste düzeni.

style.css

.search-input {
    width: 100%; padding: 1rem;
    border-radius: 30px;
    border: 2px solid #cbd5e1;
    font-size: 1.1rem;
}

.product-badge {
    background: #e0f2fe;
    color: #0369a1;
    padding: 0.25rem 0.5rem;
    border-radius: 6px;
    font-size: 0.8rem;
}

BÖLÜM 4: ASENKRON JAVASCRIPT & API PROJELERİ

Proje 20: Dad Jokes (Sohbet Balonu Tasarımı)

Tasarım Detayı: Gelen esprileri mesajlaşma uygulamasındaki sohbet balonuna yerleştiren sevimli tasarım.

style.css

.joke-bubble {
    background: #e0e7ff;
    color: #3730a3;
    padding: 1.5rem 2rem;
    border-radius: 20px 20px 20px 0;
    font-size: 1.2rem;
    position: relative;
    box-shadow: 0 4px 6px rgba(0,0,0,0.05);
}

Proje 21: Canlı Ürün Listesi ve Detay Sayfası (E-Ticaret Kartı)

Tasarım Detayı: İnternetten çekilen ürün görsellerini pürüzsüz kartlara oturtup, fiyat etiketlerini belirginleştiren arayüz.

style.css

.products-container {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 2rem;
}

.product-card {
    background: white;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 4px 10px rgba(0,0,0,0.05);
}

.product-card img {
    width: 100%; height: 220px; object-fit: cover;
}

Proje 22: Cocktails (Akıllı Grid Kartları)

Tasarım Detayı: Kokteyl tarifleri için resmin altına degrade karartma eklenmiş yarı transparan isim etiketleri.

style.css

.cocktail-card {
    position: relative;
    border-radius: 16px;
    overflow: hidden;
}

.cocktail-title {
    position: absolute;
    bottom: 0; left: 0; width: 100%;
    background: linear-gradient(transparent, rgba(0,0,0,0.8));
    color: white; padding: 1rem;
}

BÖLÜM 5: İLERİ DÜZEY KOMPLEKS UYGULAMALAR

Proje 23: Stripe Tarzı Akıllı Alt Menü (Submenus - Akışkan Yapı)

Tasarım Detayı: Fare butonların üzerinde gezdikçe alt menü kutusunun bir baloncuk gibi sola-sağa kayarak boyut değiştirmesi.

style.css

.submenu {
    position: absolute;
    background: #ffffff;
    border-radius: 10px;
    box-shadow: 0 50px 100px -20px rgba(50,50,93,0.25);
    display: none;
    padding: 1.5rem;
    transform: translateX(-50%);
    transition: all 0.25s cubic-bezier(0.075, 0.82, 0.165, 1);
}

.submenu.show { display: block; }

Proje 24: Pagination (Numaralandırılmış Küp Butonlar)

Tasarım Detayı: Aktif sayfayı parlak mavi renkle belirten, kenarları yuvarlatılmış kare sayfalama buton kümesi.

style.css

.page-btn {
    width: 40px; height: 40px;
    border: none; background: #e2e8f0;
    margin: 0 5px; border-radius: 8px;
    font-weight: bold; cursor: pointer;
}

.page-btn.active {
    background: #6366f1; color: white;
}

Proje 25: Comfy Mağazası (Tam Donanımlı Alışveriş Sepeti Arayüzü)

Tasarım Detayı: E-ticaret sitelerindeki gibi sağ taraftan kayarak gelen gölgeli sepet çekmecesi (sliding cart panel) ve dinamik listeleme alanı.

index.html

<nav class="shop-nav">
    <div class="nav-center">
        <h2>Comfy Mağazasi</h2>
        <div class="cart-btn-container">
            <button class="toggle-cart-btn">Sepet (<span class="cart-items-count">0</span>)</button>
        </div>
    </div>
</nav>

<main class="shop-container">
    <aside class="sidebar-filters">
        <h4>Filtreler</h4>
        <input type="range" class="price-filter" min="0" max="200" value="200">
        <p>Maksimum Fiyat: <span class="price-value">200</span> TL</p>
    </aside>
    <section class="products-container"></section>
</main>

<!-- Sağdan Kayarak Açılan Sepet Çekmecesi -->
<div class="cart-overlay">
    <aside class="cart-sidebar">
        <button class="close-cart">Kapat</button>
        <h3>Sepetiniz</h3>
        <div class="cart-content"></div>
        <div class="cart-footer">
            <h4>Toplam: <span class="cart-total">0 TL</span></h4>
        </div>
    </aside>
</div>

style.css

body {
    font-family: 'Segoe UI', sans-serif;
    margin: 0; background: #f8fafc;
}

.shop-nav {
    background: #ffffff; padding: 1.5rem;
    box-shadow: 0 2px 5px rgba(0,0,0,0.05);
}

.nav-center {
    display: flex; justify-content: space-between;
    max-width: 1100px; margin: 0 auto;
}

.shop-container {
    display: grid; grid-template-columns: 250px 1fr;
    max-width: 1100px; margin: 2rem auto; gap: 2rem;
}

.products-container {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 1.5rem;
}

/* Sepet Çekmecesi CSS Mimari Kodları */
.cart-overlay {
    position: fixed; top: 0; right: 0; width: 100%; height: 100%;
    background: rgba(15, 23, 42, 0.5);
    z-index: 9999; visibility: hidden; opacity: 0;
    transition: all 0.3s ease;
}

.cart-overlay.show { visibility: visible; opacity: 1; }

.cart-sidebar {
    position: fixed; top: 0; right: -400px; width: 380px; height: 100%;
    background: #ffffff; padding: 2rem; box-sizing: border-box;
    box-shadow: -5px 0 30px rgba(0,0,0,0.15);
    transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.cart-overlay.show .cart-sidebar { right: 0; }

app.js

let sepet = [];
let urunDeposu = [];

const sepetOverlay = document.querySelector(".cart-overlay");
const sepetAcBtn = document.querySelector(".toggle-cart-btn");
const sepetKapatBtn = document.querySelector(".close-cart");

sepetAcBtn.addEventListener("click", () => sepetOverlay.classList.add("show"));
sepetKapatBtn.addEventListener("click", () => sepetOverlay.classList.remove("show"));

const urunleriUzaktenCek = async () => {
    const cevap = await fetch("https://course-api.com");
    urunDeposu = await cevap.json();
    magazayiOlustur(urunDeposu);
};

function magazayiOlustur(listelenenUrunler) {
    const alan = document.querySelector(".products-container");
    alan.innerHTML = listelenenUrunler.map(u => {
        return `<article style="background:#fff; padding:1rem; border-radius:12px; box-shadow:0 4px 6px rgba(0,0,0,0.02)">
            <img src="${u.fields.image.url}" style="width:100%; height:180px; object-fit:cover; border-radius:8px;">
            <h4 style="margin:0.5rem 0">${u.fields.name}</h4>
            <p style="color:#6366f1; font-weight:bold">${u.fields.price / 100} TL</p>
            <button class="add-to-cart" data-id="${u.id}" style="background:#6366f1; color:white; border:none; padding:0.5rem 1rem; border-radius:6px; cursor:pointer; width:100%">Sepete Ekle</button>
        </article>`;
    }).join("");
    
    alan.querySelectorAll(".add-to-cart").forEach(btn => {
        btn.addEventListener("click", sepetElemanEkle);
    });
}

function sepetElemanEkle(e) {
    const id = e.target.dataset.id;
    const sepetteVarMi = sepet.find(item => item.id === id);
    if (sepetteVarMi) {
        sepetteVarMi.miktar++;
    } else {
        const urun = urunDeposu.find(item => item.id === id);
        sepet.push({ id: urun.id, isim: urun.fields.name, fiyat: urun.fields.price, miktar: 1 });
    }
    sepetiGuncelle();
}

function sepetiGuncelle() {
    const sepetOzeti = sepet.reduce((toplam, item) => {
        toplam.para += item.fiyat * item.miktar;
        toplam.adet += item.miktar;
        return toplam;
    }, { para: 0, adet: 0 });
    
    document.querySelector(".cart-total").textContent = `${sepetOzeti.para / 100} TL`;
    document.querySelector(".cart-items-count").textContent = sepetOzeti.adet;
    localStorage.setItem("comfySepet", JSON.stringify(sepet));
}

const fiyatCubugu = document.querySelector(".price-filter");
fiyatCubugu.addEventListener("input", () => {
    document.querySelector(".price-value").textContent = fiyatCubugu.value;
    const filtrelenmis = urunDeposu.filter(u => (u.fields.price / 100) <= fiyatCubugu.value);
    magazayiOlustur(filtrelenmis);
});

window.addEventListener("DOMContentLoaded", () => {
    sepet = localStorage.getItem("comfySepet") ? JSON.parse(localStorage.getItem("comfySepet")) : [];
    urunleriUzaktenCek();
    sepetiGuncelle();
});



Harika bir fikir! Geliştirdiğin tüm bu projeleri tek bir merkezden yönetebileceğin, modern, karanlık mod (dark mode) destekli ve kart tasarımlı bir Geliştirici Portfolyo Paneli (Dashboard) hazırladım.

Bu arayüz sayesinde kullanıcılar projelerini kategorilerine göre filtreleyebilecek, canlı arama yapabilecek ve her projenin üzerine gelindiğinde pürüzsüz animasyonlar görecek.

İşte projenin birbiriyle tam uyumlu HTML, CSS ve JavaScript kodları:


1. index.html (Ana Yapı)

<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Proje Portfolyo Paneli</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <!-- Yan Menü (Sidebar) -->
    <aside class="sidebar">
        <div class="logo-area">
            <div class="logo-icon">JS</div>
            <h2>JS DevPanel</h2>
        </div>
        <nav class="nav-menu">
            <button class="nav-item active" data-filter="hepsi">🚀 Tüm Projeler</button>
            <button class="nav-item" data-filter="temel">🎨 Temel DOM</button>
            <button class="nav-item" data-filter="oop">🧱 Nesne Yönelimli</button>
            <button class="nav-item" data-filter="modern">⚡ Modern ES6+</button>
            <button class="nav-item" data-filter="api">📡 API & Asenkron</button>
        </nav>
        <div class="sidebar-footer">
            <p>© 2026 Portfolyo Paneli</p>
        </div>
    </aside>

    <!-- Ana İçerik Alanı -->
    <main class="main-content">
        <!-- Üst Bar (Header) -->
        <header class="top-bar">
            <div class="search-box">
                <input type="text" id="search-input" placeholder="Projelerde ara (Örn: Sayaç, Sepet)...">
            </div>
            <div class="stats-mini">
                <span>Toplam Proje: <strong id="total-count">0</strong></span>
            </div>
        </header>

        <!-- Proje Kartları Izgarası (Grid) -->
        <section class="dashboard-grid" id="projects-grid">
            <!-- Kartlar JavaScript tarafından buraya dinamik olarak eklenecek -->
        </section>
    </main>

    <script src="app.js"></script>
</body>
</html>

2. style.css (Modern ve Akıcı Tasarım)

/* Temel Değişkenler ve Renk Paleti */
:root {
    --bg-main: #0f172a;
    --bg-sidebar: #1e293b;
    --bg-card: #334155;
    --text-main: #f8fafc;
    --text-muted: #94a3b8;
    --accent: #6366f1;
    --accent-hover: #4f46e5;
    --success: #10b981;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', system-ui, sans-serif;
    background-color: var(--bg-main);
    color: var(--text-main);
    display: flex;
    min-height: 100vh;
    overflow-x: hidden;
}

/* Yan Menü (Sidebar) Tasarımı */
.sidebar {
    width: 260px;
    background-color: var(--bg-sidebar);
    padding: 2rem 1.5rem;
    display: flex;
    flex-direction: column;
    border-right: 1px solid rgba(255,255,255,0.05);
}

.logo-area {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 3rem;
}

.logo-icon {
    background: var(--accent);
    color: white;
    font-weight: bold;
    padding: 0.5rem;
    border-radius: 8px;
    font-size: 1.2rem;
}

.logo-area h2 {
    font-size: 1.3rem;
    letter-spacing: 0.5px;
}

.nav-menu {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.nav-item {
    background: transparent;
    border: none;
    color: var(--text-muted);
    padding: 0.75rem 1rem;
    text-align: left;
    font-size: 1rem;
    font-weight: 500;
    cursor: pointer;
    border-radius: 10px;
    transition: all 0.2s ease;
}

.nav-item:hover, .nav-item.active {
    background-color: var(--accent);
    color: white;
}

.sidebar-footer {
    margin-top: auto;
    font-size: 0.8rem;
    color: var(--text-muted);
    text-align: center;
}

/* Ana İçerik Bölümü */
.main-content {
    flex: 1;
    padding: 2rem;
    display: flex;
    flex-direction: column;
    gap: 2rem;
}

/* Üst Bar Tasarımı */
.top-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: var(--bg-sidebar);
    padding: 1rem 1.5rem;
    border-radius: 16px;
    box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
}

.search-box input {
    width: 350px;
    padding: 0.75rem 1.2rem;
    background: var(--bg-main);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 12px;
    color: white;
    font-size: 0.95rem;
    transition: all 0.2s;
}

.search-box input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
}

.stats-mini {
    font-size: 1rem;
    color: var(--text-muted);
}

.stats-mini strong {
    color: var(--success);
}

/* Proje Kartları Izgarası (Grid) */
.dashboard-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1.5rem;
}

/* Kart Tasarımı ve Animasyonlar */
.project-card {
    background: var(--bg-sidebar);
    border-radius: 16px;
    padding: 1.5rem;
    border: 1px solid rgba(255,255,255,0.02);
    display: flex;
    flex-direction: column;
    gap: 1rem;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.project-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3);
    border-color: rgba(99, 102, 241, 0.3);
}

.card-tag {
    align-self: flex-start;
    padding: 0.25rem 0.6rem;
    border-radius: 6px;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    background: rgba(99, 102, 241, 0.15);
    color: #a5b4fc;
}

.project-card h3 {
    font-size: 1.2rem;
}

.project-card p {
    font-size: 0.9rem;
    color: var(--text-muted);
    line-height: 1.5;
    flex: 1; /* Butonları alta sabitlemek için esnetir */
}

.launch-btn {
    background: var(--accent);
    color: white;
    text-decoration: none;
    padding: 0.6rem 1rem;
    border-radius: 10px;
    text-align: center;
    font-size: 0.9rem;
    font-weight: 600;
    transition: background 0.2s;
}

.launch-btn:hover {
    background: var(--accent-hover);
}

3. app.js (Akıllı Filtreleme ve Arama Mekanizması)

// 1. Panelde sergilenecek proje verilerimiz
const projeler = [
    { id: 1, baslik: "Color Flipper", kategori: "temel", aciklama: "Rastgele HEX kodları üreten ve arka planı cam efekti kartıyla değiştiren uygulama.", link: "01-color-flipper/index.html" },
    { id: 2, baslik: "Gelişmiş Sayaç", kategori: "temel", aciklama: "Neumorphic tasarımlı, sayı durumuna göre renk değiştiren akıllı sayaç.", link: "02-counter/index.html" },
    { id: 3, baslik: "Müşteri Yorumları", kategori: "temel", aciklama: "Dizi verileri arasında ileri-geri butonlarıyla gezinen profil kartı.", link: "03-reviews/index.html" },
    { id: 4, baslik: "Akordeon SSS", kategori: "temel", aciklama: "Tıklandığında açılan ve diğerlerini otomatik kapatan soru-cevap kartları.", link: "06-questions/index.html" },
    { id: 5, baslik: "Restoran Menüsü", kategori: "temel", aciklama: "Yemek listesini kategorilere göre anlık süzen dinamik grid yapısı.", link: "07-menu/index.html" },
    { id: 6, baslik: "Grocery Bud", kategori: "temel", aciklama: "Local Storage destekli, eleman ekleme, silme ve düzenleme yapabilen sepet.", link: "13-grocery-bud/index.html" },
    { id: 7, baslik: "OOP Sayaç", kategori: "oop", aciklama: "JavaScript Class yapısı ile üretilmiş, sayfada çoklu çalışan bağımsız sayaçlar.", link: "15-oop-counter/index.html" },
    { id: 8, baslik: "OOP Galeri", kategori: "oop", aciklama: "Masonry ızgara sistemli ve tıklandığında açılan koyu temalı Lightbox galeri.", link: "16-oop-gallery/index.html" },
    { id: 9, baslik: "Dashboard Sayaçları", kategori: "modern", aciklama: "Açılışta sıfırdan hedefe doğru hızla sayan parlayan neon efektli sayılar.", link: "17-numbers/index.html" },
    { id: 10, baslik: "Dad Jokes API", kategori: "api", aciklama: "Uzak sunucudan asenkron veri çekerek sohbet balonu içine basan espri motoru.", link: "20-dad-jokes/index.html" },
    { id: 11, baslik: "GitHub Pagination", kategori: "api", aciklama: "Gelen büyük verileri sayfa başına 10'arlı gruplara bölen sayfalama sistemi.", link: "24-pagination/index.html" },
    { id: 12, baslik: "Comfy Mağazası", kategori: "api", aciklama: "Sağdan kayan sepet çekmeceli, fiyat çubuklu ve çoklu filtreli dev e-ticaret sistemi.", link: "25-comfy-store/index.html" }
];

// 2. DOM Elemanlarını Seçelim
const grid = document.getElementById("projects-grid");
const aramaInput = document.getElementById("search-input");
const filtreButonlari = document.querySelectorAll(".nav-item");
const toplamSayiYazisi = document.getElementById("total-count");

// 3. Projeleri Ekrana Basan Fonksiyon
function projeleriGoster(liste) {
    if (liste.length === 0) {
        grid.innerHTML = `<h3 style="grid-column: 1/-1; text-align: center; color: var(--text-muted);">Aradığınız kriterde proje bulunamadı.</h3>`;
        toplamSayiYazisi.textContent = 0;
        return;
    }

    const kartlarHtml = liste.map(proje => {
        return `
            <article class="project-card" data-category="${proje.kategori}">
                <span class="card-tag">${proje.kategori}</span>
                <h3>${proje.baslik}</h3>
                <p>${proje.aciklama}</p>
                <a href="${proje.link}" target="_blank" class="launch-btn">Projeyi Başlat 🚀</a>
            </article>
        `;
    }).join("");

    grid.innerHTML = kartlarHtml;
    toplamSayiYazisi.textContent = liste.length;
}

// 4. Kategori Filtreleme Mekanizması
filtreButonlari.forEach(buton => {
    buton.addEventListener("click", (e) => {
        // Aktif buton görsel sınıfını değiştirelim
        filtreButonlari.forEach(b => b.classList.remove("active"));
        e.currentTarget.classList.add("active");

        const kategoriIsmi = e.currentTarget.dataset.filter;
        
        // Input alanını temizleyelim ki filtre çakışmasın
        aramaInput.value = "";

        if (kategoriIsmi === "hepsi") {
            projeleriGoster(projeler);
        } else {
            const filtrelenmis = projeler.filter(p => p.kategori === kategoriIsmi);
            projeleriGoster(filtrelenmis);
        }
    });
});

// 5. Canlı Arama Mekanizması (Harf Yazıldıkça Çalışır)
aramaInput.addEventListener("keyup", () => {
    const arananKelime = aramaInput.value.toLowerCase();
    
    // Sol menüdeki aktifliği "Tüm Projeler"e çekelim ki genel arama yapsın
    filtreButonlari.forEach(b => b.classList.remove("active"));
    filtreButonlari[0].classList.add("active");

    const aramaSonuclari = projeler.filter(p => {
        return p.baslik.toLowerCase().includes(arananKelime) || 
               p.aciklama.toLowerCase().includes(arananKelime);
    });

    projeleriGoster(aramaSonuclari);
});

// 6. Sayfa İlk Açıldığında Tüm Projeleri Listele
window.addEventListener("DOMContentLoaded", () => {
    projeleriGoster(projeler);
});

Projeleri Bu Panele Nasıl Bağlayacaksınız?

Klasör yapını şu şekilde kurgularsan paneldeki Projeyi Başlat butonları hedef projeleri tarayıcıda yeni sekmede kusursuzca açacaktır:

📂 JavaScript-Portfolyom/
├── 📄 index.html  (Yukarıdaki dashboard dosyası)
├── 📄 style.css   (Yukarıdaki dashboard dosyası)
├── 📄 app.js      (Yukarıdaki dashboard dosyası)
│
├── 📂 01-color-flipper/
│   └── 📄 index.html, style.css, app.js
├── 📂 02-counter/
│   └── 📄 index.html, style.css, app.js
└── 📂 25-comfy-store/
    └── 📄 index.html, style.css, app.js