Proje Detayları

Proje Tanımı

Bu projede, JavaScript kullanarak interaktif bir quiz uygulaması geliştireceğiz. Uygulama, farklı kategorilerde sorular sunacak, kullanıcının cevaplarını değerlendirecek ve sonuçları gösterecek. Bu proje, DOM manipülasyonu, olay yönetimi, zamanlayıcılar ve veri yapıları konularını uygulamalı olarak öğrenmenize yardımcı olacak.

Adım Adım Geliştirme

Bu bölümde, quiz uygulamasını adım adım nasıl geliştirebileceğinizi öğreneceksiniz. Her adımda, ilgili kod parçalarını ve açıklamalarını bulacaksınız.

Adım 1: Proje Yapısını Oluşturma

İlk olarak, projemiz için gerekli dosyaları oluşturalım:

  • index.html - Ana HTML dosyası
  • style.css - CSS stil dosyası
  • script.js - JavaScript kod dosyası
  • questions.js - Soru veritabanı dosyası
index.html
<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Quiz Uygulaması</title>
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
</head>
<body>
    <div class="quiz-app">
        <div class="quiz-header">
            <h2>JavaScript Quiz Uygulaması</h2>
        </div>
        
        <div class="quiz-container">
            <div class="quiz-info">
                <h3>Bilgi Yarışması</h3>
                <p>Bilgilerinizi test edin ve eğlenin!</p>
            </div>
            
            <div class="quiz-start-screen" id="quizStartScreen">
                <p>Bir kategori seçin ve başlayın:</p>
                <select id="categorySelect">
                    <option value="genel">Genel Kültür</option>
                    <option value="bilim">Bilim ve Teknoloji</option>
                    <option value="tarih">Tarih</option>
                    <option value="spor">Spor</option>
                    <option value="sanat">Sanat ve Edebiyat</option>
                </select>
                <button class="quiz-button primary" id="startButton">Başla</button>
            </div>
            
            <div class="quiz-question" id="quizQuestion">
                <div class="question-number" id="questionNumber"></div>
                <div class="question-text" id="questionText"></div>
                <ul class="quiz-options" id="quizOptions"></ul>
                <div class="quiz-controls">
                    <button class="quiz-button secondary" id="prevButton">Önceki</button>
                    <button class="quiz-button primary" id="nextButton">Sonraki</button>
                </div>
                <div class="quiz-progress">
                    <div class="quiz-progress-bar" id="progressBar"></div>
                </div>
            </div>
            
            <div class="quiz-results" id="quizResults">
                <div class="results-title">Quiz Tamamlandı!</div>
                <div class="results-score" id="resultsScore"></div>
                <div class="results-message" id="resultsMessage"></div>
                
                <div class="results-stats">
                    <div class="stat-item">
                        <div class="stat-value" id="correctAnswers"></div>
                        <div class="stat-label">Doğru</div>
                    </div>
                    <div class="stat-item">
                        <div class="stat-value" id="wrongAnswers"></div>
                        <div class="stat-label">Yanlış</div>
                    </div>
                    <div class="stat-item">
                        <div class="stat-value" id="timeSpent"></div>
                        <div class="stat-label">Süre</div>
                    </div>
                </div>
                
                <button class="quiz-button primary" id="restartButton">Yeniden Başla</button>
            </div>
        </div>
    </div>

    <script src="questions.js"></script>
    <script src="script.js"></script>
</body>
</html>
style.css
/* Genel Stiller */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #f0f2f5;
    color: #333;
    line-height: 1.6;
    padding: 20px;
}

/* Quiz Uygulaması Stilleri */
.quiz-app {
    max-width: 700px;
    margin: 0 auto;
}

.quiz-header {
    text-align: center;
    margin-bottom: 20px;
}

.quiz-header h2 {
    color: #333;
    margin-bottom: 10px;
}

.quiz-container {
    background-color: #fff;
    border-radius: 10px;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
    overflow: hidden;
    position: relative;
}

.quiz-info {
    background-color: #4caf50;
    color: white;
    padding: 20px;
    text-align: center;
}

.quiz-info h3 {
    margin: 0;
    font-size: 1.5rem;
}

.quiz-info p {
    margin: 10px 0 0;
    font-size: 0.9rem;
    opacity: 0.9;
}

.quiz-start-screen {
    padding: 30px;
    text-align: center;
}

.quiz-start-screen p {
    margin-bottom: 20px;
    font-size: 1.1rem;
    color: #555;
}

.quiz-start-screen select {
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 16px;
    margin-bottom: 20px;
    width: 100%;
    max-width: 300px;
}

.quiz-question {
    padding: 30px;
    display: none;
}

.question-number {
    font-size: 0.9rem;
    color: #666;
    margin-bottom: 10px;
}

.question-text {
    font-size: 1.3rem;
    font-weight: bold;
    margin-bottom: 20px;
    color: #333;
}

.quiz-options {
    list-style-type: none;
    padding: 0;
}

.quiz-option {
    background-color: #f9f9f9;
    border: 1px solid #ddd;
    border-radius: 4px;
    padding: 15px;
    margin-bottom: 10px;
    cursor: pointer;
    transition: background-color 0.3s;
}

.quiz-option:hover {
    background-color: #f0f0f0;
}

.quiz-option.selected {
    background-color: #e3f2fd;
    border-color: #2196f3;
}

.quiz-option.correct {
    background-color: #e8f5e9;
    border-color: #4caf50;
}

.quiz-option.wrong {
    background-color: #ffebee;
    border-color: #f44336;
}

.quiz-controls {
    display: flex;
    justify-content: space-between;
    margin-top: 20px;
}

.quiz-button {
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    font-size: 16px;
    cursor: pointer;
    transition: background-color 0.3s;
}

.quiz-button.primary {
    background-color: #4caf50;
    color: white;
}

.quiz-button.primary:hover {
    background-color: #45a049;
}

.quiz-button.secondary {
    background-color: #f5f5f5;
    color: #333;
}

.quiz-button.secondary:hover {
    background-color: #e0e0e0;
}

.quiz-button:disabled {
    background-color: #cccccc;
    color: #666;
    cursor: not-allowed;
}

.quiz-results {
    padding: 30px;
    text-align: center;
    display: none;
}

.results-title {
    font-size: 1.5rem;
    font-weight: bold;
    margin-bottom: 10px;
    color: #333;
}

.results-score {
    font-size: 2.5rem;
    font-weight: bold;
    margin: 20px 0;
    color: #4caf50;
}

.results-message {
    font-size: 1.1rem;
    margin-bottom: 20px;
    color: #555;
}

.results-stats {
    display: flex;
    justify-content: center;
    margin-bottom: 30px;
}

.stat-item {
    text-align: center;
    margin: 0 15px;
}

.stat-value {
    font-size: 1.5rem;
    font-weight: bold;
    color: #333;
}

.stat-label {
    font-size: 0.9rem;
    color: #666;
}

.quiz-timer {
    position: absolute;
    top: 20px;
    right: 20px;
    background-color: rgba(255, 255, 255, 0.8);
    padding: 5px 10px;
    border-radius: 20px;
    font-size: 0.9rem;
    color: #333;
}

.quiz-progress {
    height: 5px;
    background-color: #e0e0e0;
    margin-top: 20px;
    border-radius: 5px;
    overflow: hidden;
}

.quiz-progress-bar {
    height: 100%;
    background-color: #4caf50;
    width: 0;
    transition: width 0.3s;
}

/* Responsive Tasarım */
@media (max-width: 768px) {
    .quiz-container {
        border-radius: 0;
    }
    
    .quiz-question {
        padding: 20px;
    }
    
    .question-text {
        font-size: 1.1rem;
    }
    
    .quiz-option {
        padding: 12px;
    }
    
    .results-stats {
        flex-direction: column;
        gap: 15px;
    }
}

Adım 2: Soru Veritabanını Oluşturma

Şimdi, quiz uygulaması için soru veritabanını oluşturalım. Bu, farklı kategorilerde soruları içeren bir JavaScript dosyası olacak:

questions.js
// Soru veritabanı
const quizQuestions = {
    // Genel Kültür Soruları
    genel: [
        {
            question: "Türkiye'nin başkenti hangi şehirdir?",
            options: ["İstanbul", "Ankara", "İzmir", "Bursa"],
            answer: 1
        },
        {
            question: "Dünyanın en büyük okyanusu hangisidir?",
            options: ["Atlantik Okyanusu", "Hint Okyanusu", "Pasifik Okyanusu", "Arktik Okyanusu"],
            answer: 2
        },
        {
            question: "Hangi gezegen Güneş Sistemi'nde en büyüktür?",
            options: ["Mars", "Venüs", "Dünya", "Jüpiter"],
            answer: 3
        },
        {
            question: "İnsan vücudundaki en büyük organ hangisidir?",
            options: ["Kalp", "Beyin", "Deri", "Karaciğer"],
            answer: 2
        },
        {
            question: "Hangi ülke dünyanın en kalabalık nüfusuna sahiptir?",
            options: ["Hindistan", "ABD", "Çin", "Endonezya"],
            answer: 2
        },
        {
            question: "Hangi element periyodik tabloda 'Fe' sembolü ile gösterilir?",
            options: ["Flor", "Demir", "Fosfor", "Fermiyum"],
            answer: 1
        },
        {
            question: "Bir yıl kaç saniyedir?",
            options: ["31,536,000", "86,400", "525,600", "3,600"],
            answer: 0
        },
        {
            question: "Hangi hayvan uçabilen tek memelidir?",
            options: ["Penguen", "Yarasa", "Sincap", "Kanguru"],
            answer: 1
        },
        {
            question: "Hangi renk gökkuşağında bulunmaz?",
            options: ["Mor", "Siyah", "Yeşil", "Turuncu"],
            answer: 1
        },
        {
            question: "Dünya'nın en uzun nehri hangisidir?",
            options: ["Amazon Nehri", "Nil Nehri", "Yangtze Nehri", "Mississippi Nehri"],
            answer: 1
        }
    ],
    
    // Bilim ve Teknoloji Soruları
    bilim: [
        {
            question: "Işık hızı yaklaşık olarak kaç km/saniyedir?",
            options: ["150,000 km/s", "300,000 km/s", "500,000 km/s", "1,000,000 km/s"],
            answer: 1
        },
        {
            question: "Hangi bilim insanı Görelilik Teorisi'ni geliştirmiştir?",
            options: ["Isaac Newton", "Nikola Tesla", "Albert Einstein", "Stephen Hawking"],
            answer: 2
        },
        {
            question: "DNA'nın açılımı nedir?",
            options: ["Deoksiribonükleik Asit", "Dinamik Nükleik Asit", "Deoksiriboz Nükleik Asit", "Dinamik Nükleotid Asit"],
            answer: 0
        },
        {
            question: "Hangi gezegen Güneş'e en yakındır?",
            options: ["Venüs", "Mars", "Merkür", "Dünya"],
            answer: 2
        },
        {
            question: "Hangi element periyodik tabloda en yaygın olanıdır?",
            options: ["Oksijen", "Karbon", "Hidrojen", "Demir"],
            answer: 2
        },
        {
            question: "İlk kişisel bilgisayar hangi şirket tarafından üretilmiştir?",
            options: ["IBM", "Apple", "Microsoft", "Intel"],
            answer: 1
        },
        {
            question: "Hangi bilim dalı canlıları inceler?",
            options: ["Fizik", "Kimya", "Biyoloji", "Jeoloji"],
            answer: 2
        },
        {
            question: "Hangi vitamin eksikliği skorbüt hastalığına neden olur?",
            options: ["A Vitamini", "B Vitamini", "C Vitamini", "D Vitamini"],
            answer: 2
        },
        {
            question: "Hangi gezegen 'Kızıl Gezegen' olarak bilinir?",
            options: ["Jüpiter", "Mars", "Venüs", "Satürn"],
            answer: 1
        },
        {
            question: "İnternet'in temelini oluşturan ağ protokolü hangisidir?",
            options: ["HTTP", "FTP", "TCP/IP", "SMTP"],
            answer: 2
        }
    ],
    
    // Tarih Soruları
    tarih: [
        {
            question: "İstanbul'un fethi hangi yılda gerçekleşmiştir?",
            options: ["1453", "1299", "1517", "1683"],
            answer: 0
        },
        {
            question: "I. Dünya Savaşı hangi yıllar arasında gerçekleşmiştir?",
            options: ["1905-1910", "1914-1918", "1939-1945", "1922-1927"],
            answer: 1
        },
        {
            question: "Türkiye Cumhuriyeti hangi tarihte ilan edilmiştir?",
            options: ["29 Ekim 1920", "23 Nisan 1920", "29 Ekim 1923", "30 Ağustos 1922"],
            answer: 2
        },
        {
            question: "Amerika'yı keşfeden denizci kimdir?",
            options: ["Vasco da Gama", "Ferdinand Magellan", "Kristof Kolomb", "James Cook"],
            answer: 2
        },
        {
            question: "Fransız Devrimi hangi yılda başlamıştır?",
            options: ["1789", "1804", "1776", "1815"],
            answer: 0
        },
        {
            question: "Osmanlı İmparatorluğu'nun kurucusu kimdir?",
            options: ["Fatih Sultan Mehmet", "Yavuz Sultan Selim", "Osman Bey", "Kanuni Sultan Süleyman"],
            answer: 2
        },
        {
            question: "Hangi antik uygarlık piramitleri inşa etmiştir?",
            options: ["Yunan", "Roma", "Mısır", "Çin"],
            answer: 2
        },
        {
            question: "II. Dünya Savaşı hangi yılda sona ermiştir?",
            options: ["1943", "1944", "1945", "1946"],
            answer: 2
        },
        {
            question: "Magna Carta hangi ülkede imzalanmıştır?",
            options: ["Fransa", "İngiltere", "İtalya", "Almanya"],
            answer: 1
        },
        {
            question: "Hangi Türk lider 'Atatürk' soyadını almıştır?",
            options: ["İsmet İnönü", "Mustafa Kemal", "Fevzi Çakmak", "Kazım Karabekir"],
            answer: 1
        }
    ],
    
    // Spor Soruları
    spor: [
        {
            question: "Bir futbol maçında her takımda kaç oyuncu bulunur?",
            options: ["9", "10", "11", "12"],
            answer: 2
        },
        {
            question: "Hangi spor dalında 'Grand Slam' turnuvaları düzenlenir?",
            options: ["Golf", "Tenis", "Futbol", "Basketbol"],
            answer: 1
        },
        {
            question: "Olimpiyat bayrağında kaç halka vardır?",
            options: ["4", "5", "6", "7"],
            answer: 1
        },
        {
            question: "Bir basketbol potasının yerden yüksekliği kaç metredir?",
            options: ["2.74 m", "3.05 m", "3.25 m", "3.50 m"],
            answer: 1
        },
        {
            question: "Hangi ülke futbolda en çok Dünya Kupası kazanmıştır?",
            options: ["Almanya", "İtalya", "Arjantin", "Brezilya"],
            answer: 3
        },
        {
            question: "Bir maraton yarışı kaç kilometredir?",
            options: ["36.5 km", "40.2 km", "42.195 km", "45 km"],
            answer: 2
        },
        {
            question: "Hangi spor dalında 'hat-trick' terimi kullanılır?",
            options: ["Basketbol", "Futbol", "Voleybol", "Tenis"],
            answer: 1
        },
        {
            question: "Formula 1 yarışlarında bir pilot hangi bayrağı gördüğünde yarışı bırakmalıdır?",
            options: ["Kırmızı", "Sarı", "Siyah", "Mavi"],
            answer: 2
        },
        {
            question: "Bir voleybol takımında kaç oyuncu sahada bulunur?",
            options: ["5", "6", "7", "8"],
            answer: 1
        },
        {
            question: "Hangi spor dalında 'birdie', 'eagle' ve 'bogey' terimleri kullanılır?",
            options: ["Tenis", "Golf", "Kriket", "Beyzbol"],
            answer: 1
        }
    ],
    
    // Sanat ve Edebiyat Soruları
    sanat: [
        {
            question: "Mona Lisa tablosunun ressamı kimdir?",
            options: ["Vincent van Gogh", "Pablo Picasso", "Leonardo da Vinci", "Michelangelo"],
            answer: 2
        },
        {
            question: "Hangi yazar 'Suç ve Ceza' romanını yazmıştır?",
            options: ["Leo Tolstoy", "Fyodor Dostoyevski", "Anton Çehov", "Franz Kafka"],
            answer: 1
        },
        {
            question: "Hangi müzik türü 1950'lerde ABD'de ortaya çıkmıştır?",
            options: ["Jazz", "Rock and Roll", "Hip Hop", "Elektronik"],
            answer: 1
        },
        {
            question: "'Guernica' tablosu hangi ressama aittir?",
            options: ["Salvador Dali", "Pablo Picasso", "Claude Monet", "Frida Kahlo"],
            answer: 1
        },
        {
            question: "Hangi yazar 'Romeo ve Juliet' oyununu yazmıştır?",
            options: ["Charles Dickens", "Jane Austen", "William Shakespeare", "Oscar Wilde"],
            answer: 2
        },
        {
            question: "Hangi müzik aleti yaylı çalgılar ailesine aittir?",
            options: ["Flüt", "Piyano", "Keman", "Trompet"],
            answer: 2
        },
        {
            question: "'Yüzüklerin Efendisi' serisinin yazarı kimdir?",
            options: ["J.K. Rowling", "J.R.R. Tolkien", "George R.R. Martin", "C.S. Lewis"],
            answer: 1
        },
        {
            question: "Hangi sanat akımı 'gerçeküstücülük' olarak bilinir?",
            options: ["Empresyonizm", "Kübizm", "Sürrealizm", "Ekspresyonizm"],
            answer: 2
        },
        {
            question: "Hangi Türk yazar 'İnce Memed' romanını yazmıştır?",
            options: ["Orhan Pamuk", "Yaşar Kemal", "Nazım Hikmet", "Sabahattin Ali"],
            answer: 1
        },
        {
            question: "Sistine Şapeli'nin tavanını kim resimlemiştir?",
            options: ["Leonardo da Vinci", "Raphael", "Michelangelo", "Donatello"],
            answer: 2
        }
    ]
};

Adım 3: JavaScript Kodunu Yazma

Şimdi, uygulamanın işlevselliğini sağlayacak JavaScript kodunu yazalım:

script.js
// DOM elementlerini seçme
const quizStartScreen = document.getElementById('quizStartScreen');
const quizQuestion = document.getElementById('quizQuestion');
const quizResults = document.getElementById('quizResults');
const categorySelect = document.getElementById('categorySelect');
const startButton = document.getElementById('startButton');
const questionNumber = document.getElementById('questionNumber');
const questionText = document.getElementById('questionText');
const quizOptions = document.getElementById('quizOptions');
const prevButton = document.getElementById('prevButton');
const nextButton = document.getElementById('nextButton');
const progressBar = document.getElementById('progressBar');
const resultsScore = document.getElementById('resultsScore');
const resultsMessage = document.getElementById('resultsMessage');
const correctAnswers = document.getElementById('correctAnswers');
const wrongAnswers = document.getElementById('wrongAnswers');
const timeSpent = document.getElementById('timeSpent');
const restartButton = document.getElementById('restartButton');

// Quiz durumu
let currentQuestions = [];
let currentQuestionIndex = 0;
let userAnswers = [];
let startTime;
let timerInterval;
let quizTimer;

// Sayfa yüklendiğinde
document.addEventListener('DOMContentLoaded', () => {
    // Başlat butonuna tıklama olayı
    startButton.addEventListener('click', startQuiz);
    
    // Önceki butonu olayı
    prevButton.addEventListener('click', showPreviousQuestion);
    
    // Sonraki butonu olayı
    nextButton.addEventListener('click', () => {
        // Eğer son soru ise, quizi bitir
        if (currentQuestionIndex === currentQuestions.length - 1) {
            finishQuiz();
        } else {
            // Değilse, sonraki soruya geç
            showNextQuestion();
        }
    });
    
    // Yeniden başlat butonu olayı
    restartButton.addEventListener('click', () => {
        // Quiz başlangıç ekranını göster
        quizResults.style.display = 'none';
        quizStartScreen.style.display = 'block';
    });
});

// Quiz'i başlatma fonksiyonu
function startQuiz() {
    // Seçilen kategoriyi al
    const selectedCategory = categorySelect.value;
    
    // Seçilen kategorideki soruları al
    currentQuestions = quizQuestions[selectedCategory];
    
    // Soruları karıştır
    shuffleArray(currentQuestions);
    
    // İlk 10 soruyu al (veya daha az varsa tümünü)
    currentQuestions = currentQuestions.slice(0, 10);
    
    // Quiz durumunu sıfırla
    currentQuestionIndex = 0;
    userAnswers = Array(currentQuestions.length).fill(null);
    
    // Başlangıç ekranını gizle, soru ekranını göster
    quizStartScreen.style.display = 'none';
    quizQuestion.style.display = 'block';
    
    // İlk soruyu göster
    showQuestion(0);
    
    // Zamanlayıcıyı başlat
    startTime = new Date();
    
    // Zamanlayıcı elementi oluştur
    if (!quizTimer) {
        quizTimer = document.createElement('div');
        quizTimer.className = 'quiz-timer';
        document.querySelector('.quiz-container').appendChild(quizTimer);
    }
    
    // Zamanlayıcıyı güncelle
    updateTimer();
    timerInterval = setInterval(updateTimer, 1000);
}

// Soruyu gösterme fonksiyonu
function showQuestion(index) {
    // Geçerli soru indeksini güncelle
    currentQuestionIndex = index;
    
    // Soru numarasını güncelle
    questionNumber.textContent = `Soru ${index + 1}/${currentQuestions.length}`;
    
    // Soru metnini güncelle
    questionText.textContent = currentQuestions[index].question;
    
    // Seçenekleri temizle
    quizOptions.innerHTML = '';
    
    // Seçenekleri ekle
    currentQuestions[index].options.forEach((option, i) => {
        const li = document.createElement('li');
        li.className = 'quiz-option';
        li.textContent = `${String.fromCharCode(65 + i)}) ${option}`;
        
        // Kullanıcı daha önce bu seçeneği seçtiyse, seçili olarak işaretle
        if (userAnswers[index] === i) {
            li.classList.add('selected');
        }
        
        // Seçeneğe tıklama olayı
        li.addEventListener('click', () => {
            // Tüm seçeneklerden 'selected' sınıfını kaldır
            document.querySelectorAll('.quiz-option').forEach(opt => {
                opt.classList.remove('selected');
            });
            
            // Seçilen seçeneğe 'selected' sınıfını ekle
            li.classList.add('selected');
            
            // Kullanıcının cevabını kaydet
            userAnswers[index] = i;
            
            // Sonraki butonunu etkinleştir
            nextButton.disabled = false;
        });
        
        quizOptions.appendChild(li);
    });
    
    // Önceki ve sonraki butonlarını güncelle
    prevButton.disabled = index === 0;
    nextButton.disabled = userAnswers[index] === null;
    
    // Son soru ise, sonraki butonunun metnini değiştir
    if (index === currentQuestions.length - 1) {
        nextButton.textContent = 'Bitir';
    } else {
        nextButton.textContent = 'Sonraki';
    }
    
    // İlerleme çubuğunu güncelle
    updateProgressBar();
}

// Önceki soruyu gösterme fonksiyonu
function showPreviousQuestion() {
    if (currentQuestionIndex > 0) {
        showQuestion(currentQuestionIndex - 1);
    }
}

// Sonraki soruyu gösterme fonksiyonu
function showNextQuestion() {
    if (currentQuestionIndex < currentQuestions.length - 1) {
        showQuestion(currentQuestionIndex + 1);
    }
}

// Quiz'i bitirme fonksiyonu
function finishQuiz() {
    // Zamanlayıcıyı durdur
    clearInterval(timerInterval);
    
    // Soru ekranını gizle, sonuç ekranını göster
    quizQuestion.style.display = 'none';
    quizResults.style.display = 'block';
    
    // Doğru cevap sayısını hesapla
    const correct = userAnswers.reduce((count, answer, index) => {
        return count + (answer === currentQuestions[index].answer ? 1 : 0);
    }, 0);
    
    // Yanlış cevap sayısını hesapla
    const wrong = currentQuestions.length - correct;
    
    // Sonuç metnini güncelle
    resultsScore.textContent = `${correct}/${currentQuestions.length}`;
    
    // Doğru ve yanlış sayılarını güncelle
    correctAnswers.textContent = correct;
    wrongAnswers.textContent = wrong;
    
    // Geçen süreyi hesapla
    const endTime = new Date();
    const timeDiff = Math.floor((endTime - startTime) / 1000); // saniye cinsinden
    const minutes = Math.floor(timeDiff / 60);
    const seconds = timeDiff % 60;
    timeSpent.textContent = `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
    
    // Sonuç mesajını güncelle
    if (correct === currentQuestions.length) {
        resultsMessage.textContent = 'Mükemmel! Tüm soruları doğru cevapladınız.';
    } else if (correct >= currentQuestions.length * 0.7) {
        resultsMessage.textContent = 'Tebrikler! Harika bir performans gösterdiniz.';
    } else if (correct >= currentQuestions.length * 0.5) {
        resultsMessage.textContent = 'İyi iş! Yarıdan fazla soruyu doğru cevapladınız.';
    } else {
        resultsMessage.textContent = 'Daha fazla pratik yaparak gelişebilirsiniz.';
    }
    
    // Zamanlayıcıyı kaldır
    if (quizTimer) {
        quizTimer.remove();
        quizTimer = null;
    }
    
    // Sonuçları localStorage'a kaydet
    saveQuizResults(categorySelect.value, correct, currentQuestions.length, timeDiff);
}

// İlerleme çubuğunu güncelleme fonksiyonu
function updateProgressBar() {
    const progress = ((currentQuestionIndex + 1) / currentQuestions.length) * 100;
    progressBar.style.width = `${progress}%`;
}

// Zamanlayıcıyı güncelleme fonksiyonu
function updateTimer() {
    const currentTime = new Date();
    const timeDiff = Math.floor((currentTime - startTime) / 1000); // saniye cinsinden
    const minutes = Math.floor(timeDiff / 60);
    const seconds = timeDiff % 60;
    quizTimer.textContent = `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
}

// Diziyi karıştırma fonksiyonu (Fisher-Yates algoritması)
function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
    return array;
}

// Quiz sonuçlarını kaydetme fonksiyonu
function saveQuizResults(category, correct, total, time) {
    // Önceki sonuçları al
    let quizHistory = JSON.parse(localStorage.getItem('quizHistory')) || [];
    
    // Yeni sonucu ekle
    quizHistory.push({
        category,
        correct,
        total,
        time,
        date: new Date().toISOString()
    });
    
    // En fazla 10 sonuç sakla
    if (quizHistory.length > 10) {
        quizHistory = quizHistory.slice(-10);
    }
    
    // Sonuçları kaydet
    localStorage.setItem('quizHistory', JSON.stringify(quizHistory));
}

Adım 4: Uygulamayı Test Etme

Şimdi uygulamanızı test etme zamanı! Aşağıdaki adımları izleyin:

  1. Tüm dosyaları (index.htmlstyle.cssscript.jsquestions.js) aynı klasöre kaydedin.
  2. HTML dosyasını bir web tarayıcısında açın.
  3. Bir kategori seçin ve "Başla" butonuna tıklayın.
  4. Soruları cevaplayın ve ilerleyin.
  5. Quiz'i tamamladıktan sonra sonuçlarınızı görün.

İpucu: Uygulamanızı test ederken, farklı tarayıcılarda ve cihazlarda (masaüstü, tablet, mobil) nasıl göründüğünü kontrol edin. Responsive tasarımın doğru çalıştığından emin olun.

Projeyi Geliştirme

Temel quiz uygulamasını başarıyla oluşturduktan sonra, aşağıdaki özelliklerle projenizi geliştirebilirsiniz:

1. Soru Süresi Sınırlaması

Her soru için bir süre sınırlaması ekleyebilirsiniz. Süre dolduğunda, otomatik olarak sonraki soruya geçilebilir veya cevap verilemez hale getirilebilir:

question-timer.js
// Soru zamanlayıcısı için değişkenler
let questionTimer;
let questionTimeLeft;
const QUESTION_TIME = 20; // Her soru için 20 saniye

// Soru zamanlayıcısı elementi oluştur
const questionTimerElement = document.createElement('div');
questionTimerElement.className = 'question-timer';
quizQuestion.appendChild(questionTimerElement);

// Soruyu gösterme fonksiyonunu güncelle
function showQuestion(index) {
    // ... mevcut kod ...
    
    // Önceki zamanlayıcıyı temizle
    if (questionTimer) {
        clearInterval(questionTimer);
    }
    
    // Soru zamanlayıcısını başlat
    startQuestionTimer();
    
    // ... mevcut kod ...
}

// Soru zamanlayıcısını başlatma fonksiyonu
function startQuestionTimer() {
    questionTimeLeft = QUESTION_TIME;
    updateQuestionTimer();
    
    questionTimer = setInterval(() => {
        questionTimeLeft--;
        updateQuestionTimer();
        
        if (questionTimeLeft <= 0) {
            // Zamanlayıcıyı durdur
            clearInterval(questionTimer);
            
            // Süre dolduğunda yapılacak işlem
            if (userAnswers[currentQuestionIndex] === null) {
                // Kullanıcı cevap vermediyse, otomatik olarak boş bırak
                userAnswers[currentQuestionIndex] = -1; // -1, cevap verilmedi anlamında
            }
            
            // Son soru değilse, sonraki soruya geç
            if (currentQuestionIndex < currentQuestions.length - 1) {
                showNextQuestion();
            } else {
                // Son soru ise, quizi bitir
                finishQuiz();
            }
        }
    }, 1000);
}

// Soru zamanlayıcısını güncelleme fonksiyonu
function updateQuestionTimer() {
    questionTimerElement.textContent = `Kalan Süre: ${questionTimeLeft}s`;
    
    // Süre azaldıkça rengi değiştir
    if (questionTimeLeft <= 5) {
        questionTimerElement.style.color = '#f44336'; // Kırmızı
    } else if (questionTimeLeft <= 10) {
        questionTimerElement.style.color = '#ff9800'; // Turuncu
    } else {
        questionTimerElement.style.color = '#4caf50'; // Yeşil
    }
}

2. Zorluk Seviyeleri

Farklı zorluk seviyelerinde sorular ekleyebilirsiniz:

difficulty-levels.js
// HTML'e zorluk seviyesi seçimi ekleyin
// <select id="difficultySelect">
//     <option value="kolay">Kolay</option>
//     <option value="orta">Orta</option>
//     <option value="zor">Zor</option>
// </select>

// Zorluk seviyesi seçimini al
const difficultySelect = document.getElementById('difficultySelect');

// Soru veritabanını zorluk seviyelerine göre düzenleyin
const quizQuestionsByDifficulty = {
    genel: {
        kolay: [ /* Kolay sorular */ ],
        orta: [ /* Orta zorlukta sorular */ ],
        zor: [ /* Zor sorular */ ]
    },
    // Diğer kategoriler...
};

// Quiz'i başlatma fonksiyonunu güncelle
function startQuiz() {
    // Seçilen kategori ve zorluk seviyesini al
    const selectedCategory = categorySelect.value;
    const selectedDifficulty = difficultySelect.value;
    
    // Seçilen kategori ve zorluk seviyesindeki soruları al
    currentQuestions = quizQuestionsByDifficulty[selectedCategory][selectedDifficulty];
    
    // ... mevcut kod ...
}

3. Soru İpuçları

Her soru için ipucu ekleyebilir ve kullanıcıların ihtiyaç duyduklarında bu ipuçlarını görmelerini sağlayabilirsiniz:

question-hints.js
// Soru veritabanına ipuçları ekleyin
const quizQuestionsWithHints = {
    genel: [
        {
            question: "Türkiye'nin başkenti hangi şehirdir?",
            options: ["İstanbul", "Ankara", "İzmir", "Bursa"],
            answer: 1,
            hint: "1923'te Cumhuriyet'in ilanından sonra başkent olmuştur."
        },
        // Diğer sorular...
    ],
    // Diğer kategoriler...
};

// HTML'e ipucu butonu ekleyin
// <button class="quiz-button secondary" id="hintButton">İpucu</button>

// İpucu butonunu seç
const hintButton = document.getElementById('hintButton');

// İpucu elementi oluştur
const hintElement = document.createElement('div');
hintElement.className = 'question-hint';
hintElement.style.display = 'none';
quizQuestion.appendChild(hintElement);

// İpucu butonuna tıklama olayı
hintButton.addEventListener('click', showHint);

// İpucu gösterme fonksiyonu
function showHint() {
    // İpucu metnini güncelle
    hintElement.textContent = currentQuestions[currentQuestionIndex].hint;
    
    // İpucu elementini göster
    hintElement.style.display = 'block';
    
    // İpucu butonunu devre dışı bırak
    hintButton.disabled = true;
    
    // İpucu kullanımını kaydet (puanı azaltmak için)
    hintsUsed++;
}

// Soruyu gösterme fonksiyonunu güncelle
function showQuestion(index) {
    // ... mevcut kod ...
    
    // İpucu elementini gizle ve butonu sıfırla
    hintElement.style.display = 'none';
    hintButton.disabled = false;
    
    // ... mevcut kod ...
}

4. Sonuç Grafiği

Quiz sonuçlarını görsel olarak göstermek için bir grafik ekleyebilirsiniz:

results-chart.js
// HTML'e grafik için bir canvas ekleyin
// <canvas id="resultsChart" width="400" height="200"></canvas>

// Quiz'i bitirme fonksiyonunu güncelle
function finishQuiz() {
    // ... mevcut kod ...
    
    // Sonuç grafiğini oluştur
    createResultsChart();
    
    // ... mevcut kod ...
}

// Sonuç grafiği oluşturma fonksiyonu
function createResultsChart() {
    const canvas = document.getElementById('resultsChart');
    const ctx = canvas.getContext('2d');
    
    // Grafik verilerini hazırla
    const correct = userAnswers.reduce((count, answer, index) => {
        return count + (answer === currentQuestions[index].answer ? 1 : 0);
    }, 0);
    
    const wrong = currentQuestions.length - correct;
    
    // Grafik ayarları
    const chartWidth = canvas.width;
    const chartHeight = canvas.height;
    const barHeight = 40;
    const maxBarWidth = chartWidth - 100;
    
    // Arkaplanı temizle
    ctx.clearRect(0, 0, chartWidth, chartHeight);
    
    // Doğru cevaplar çubuğu
    ctx.fillStyle = '#4caf50';
    const correctBarWidth = (correct / currentQuestions.length) * maxBarWidth;
    ctx.fillRect(80, 50, correctBarWidth, barHeight);
    
    // Yanlış cevaplar çubuğu
    ctx.fillStyle = '#f44336';
    const wrongBarWidth = (wrong / currentQuestions.length) * maxBarWidth;
    ctx.fillRect(80, 110, wrongBarWidth, barHeight);
    
    // Etiketler
    ctx.fillStyle = '#333';
    ctx.font = '14px Arial';
    ctx.fillText('Doğru', 20, 75);
    ctx.fillText('Yanlış', 20, 135);
    
    // Değerler
    ctx.fillStyle = '#333';
    ctx.font = '14px Arial';
    ctx.fillText(`${correct}`, correctBarWidth + 90, 75);
    ctx.fillText(`${wrong}`, wrongBarWidth + 90, 135);
}

Geliştirme Zorlukları

Quiz uygulamanızı daha da geliştirmek için aşağıdaki zorlukları deneyebilirsiniz:

  1. Çoklu Oyuncu Modu: İki veya daha fazla oyuncunun aynı cihazda sırayla oynayabilmesini sağlayan bir mod ekleyin.
  2. Soru Ekleme Paneli: Kullanıcıların kendi sorularını ekleyebilmesini sağlayan bir panel oluşturun.
  3. Yüksek Skor Tablosu: En iyi sonuçları gösteren bir yüksek skor tablosu ekleyin.
  4. Ses Efektleri: Doğru ve yanlış cevaplar için ses efektleri ekleyin.
  5. Sosyal Medya Paylaşımı: Kullanıcıların sonuçlarını sosyal medyada paylaşabilmesini sağlayın.

Sonuç ve Öğrenilen Dersler

Bu projede, JavaScript kullanarak interaktif bir quiz uygulaması geliştirdik. Bu süreçte şunları öğrendik:

  • DOM elementlerini dinamik olarak oluşturmayı ve manipüle etmeyi
  • JavaScript ile form kontrolü ve kullanıcı girdilerini işlemeyi
  • Zamanlayıcılar ve geri sayım işlevselliği eklemeyi
  • Veri yapılarını (diziler, nesneler) etkili bir şekilde kullanmayı
  • Uygulama durumunu yönetmeyi ve farklı ekranlar arasında geçiş yapmayı
  • LocalStorage kullanarak kullanıcı verilerini kaydetmeyi
  • Responsive tasarım ilkelerini uygulamayı

Bu proje, modern web geliştirme becerilerinizi geliştirmenize ve gerçek dünya uygulamaları oluşturmanıza yardımcı olacak temel bilgileri sağlamıştır. Öğrendiğiniz teknikleri ve kavramları kullanarak, daha karmaşık ve özelleştirilmiş web uygulamaları geliştirebilirsiniz.