Newer
Older
2025-Otaki / system / phlox-quiz1.html
@Otaki Otaki on 26 Aug 7 KB add color
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>音の強弱編</title>
  <link rel="stylesheet" href="phlox.css" />
  <style>
    /* 新しい表示形式に合わせてCSSを調整 */
    .quiz-container {
      max-width: 600px;
      margin: 2em auto;
      padding: 1.5em;
      border: 1px solid #ddd;
      border-radius: 8px;
    }
    .question-box {
      margin-bottom: 1.5em;
    }
    .choices-list {
      list-style-type: none;
      padding: 0;
    }
    .choices-list li {
      margin-bottom: 0.5em;
    }
    .choices-list button {
      width: 100%;
      padding: 0.8em;
      font-size: 1.1em;
      text-align: left;
      border: 1px solid #ccc;
      background-color: #f9f9f9;
      cursor: pointer;
      border-radius: 5px;
      transition: background-color 0.3s;
    }
    .choices-list button:hover {
      background-color: #eaeaea;
    }
    .explanation-box {
      margin-top: 2em;
      padding: 1em;
      border-left: 5px solid #007bff;
      background-color: #7a9ac4; /* 変更: 元の#5c7cb3より少し薄い青 */
      color: #f0f0f0; /* bodyの文字色と合わせる */
      border-radius: 4px;
      display: none; /* 初期状態では非表示 */
    }
    .explanation-box.correct {
      border-color: #28a745;
      background-color: #69a369; /* 変更: 元の#538853より少し薄い緑 */
    }
    .explanation-box.incorrect {
      border-color: #dc3545;
      background-color: #ce7575; /* 変更: 元の#b05c5cより少し薄い赤 */
    }
    .navigation-buttons {
      text-align: center;
      margin-top: 1.5em;
    }
  </style>
</head>
<body>
  <h1>ここは音の強弱についてのクイズ</h1>
  <div id="timer" style="font-size: 1.5em; margin-bottom: 1em; text-align: center;">タイム: 00:00</div>
  
  <div class="quiz-container">
    <div id="quiz-question-box">
      </div>
    
    <div id="explanation-container" class="explanation-box">
      </div>
    
    <div class="navigation-buttons">
      <button id="next-button" style="display: none;">次の問題へ</button>
      <button id="show-results-button" style="display: none;">結果を見る</button>
    </div>
  </div>

  <script>
    let quizData = [];
    let currentQuestionIndex = 0;
    let userAnswers = [];
    let startTime;
    let timerInterval;

    function updateTimer() {
      const currentTime = new Date().getTime();
      const elapsedTime = Math.floor((currentTime - startTime) / 1000);
      const minutes = String(Math.floor(elapsedTime / 60)).padStart(2, '0');
      const seconds = String(elapsedTime % 60).padStart(2, '0');
      document.getElementById('timer').textContent = `タイム: ${minutes}:${seconds}`;
    }

    function shuffle(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;
    }

    async function loadCSV() {
      const res = await fetch("phlox-quiz1.csv?ts=" + Date.now());
      const text = await res.text();
      const lines = text.trim().split("\n").filter(line => line.trim() !== "");

      for (let i = 1; i < lines.length; i++) {
        const row = lines[i].match(/(".*?"|[^",]+)(?=\s*,|\s*$)/g)?.map(s => s.replace(/^"|"$/g, ""));
        if (!row || row.length < 5) continue;

        const [question, c1 = "", c2 = "", c3 = "", c4 = "", correctNumStr = "", explanation = ""] = row;
        const rawChoices = [c1, c2, c3, c4];
        const choices = rawChoices.filter(c => c.trim() !== "");
        const correctIndex = parseInt(correctNumStr, 10) - 1;
        const correctAnswer = rawChoices[correctIndex];

        quizData.push({
          question: question,
          choices: choices,
          correct: correctAnswer,
          explanation: explanation
        });
      }

      // クイズデータをシャッフル
      quizData = shuffle(quizData);

      // 最初の問題を表示
      renderQuestion();
      
      startTime = new Date().getTime();
      timerInterval = setInterval(updateTimer, 1000);
    }

    // 問題を表示する関数
    function renderQuestion() {
      const quizQuestionBox = document.getElementById("quiz-question-box");
      const explanationContainer = document.getElementById("explanation-container");
      const nextButton = document.getElementById("next-button");
      const showResultsButton = document.getElementById("show-results-button");

      // 前回表示した解説やボタンを非表示にする
      explanationContainer.style.display = 'none';
      nextButton.style.display = 'none';
      showResultsButton.style.display = 'none';

      // 最後の問題の場合は終了ボタンを表示
      if (currentQuestionIndex >= quizData.length) {
        endQuiz();
        return;
      }
      
      const q = quizData[currentQuestionIndex];
      const shuffledChoices = shuffle([...q.choices]);
      
      let html = `
        <div class="question-box">
          <h2>Q${currentQuestionIndex + 1}. ${q.question}</h2>
          <ul class="choices-list">
      `;
      
      shuffledChoices.forEach(choice => {
        html += `<li><button class="choice-button" data-choice="${choice}">${choice}</button></li>`;
      });
      
      html += `</ul></div>`;
      quizQuestionBox.innerHTML = html;

      // 選択肢ボタンにイベントリスナーを追加
      document.querySelectorAll(".choice-button").forEach(button => {
        button.addEventListener("click", handleAnswer);
      });
    }

    // 回答がクリックされたときの処理
    function handleAnswer(event) {
      const selectedChoice = event.target.dataset.choice;
      const currentQuestion = quizData[currentQuestionIndex];
      const isCorrect = selectedChoice === currentQuestion.correct;
      
      userAnswers.push({
        userAnswer: selectedChoice,
        correctAnswer: currentQuestion.correct,
        isCorrect: isCorrect
      });
      
      // 選択肢ボタンを無効化
      document.querySelectorAll(".choice-button").forEach(button => {
        button.disabled = true;
        if (button.dataset.choice === currentQuestion.correct) {
          button.style.backgroundColor = '#d4edda';
        } else if (button.dataset.choice === selectedChoice) {
          button.style.backgroundColor = '#f8d7da';
        }
      });
      
      // 解説を表示
      const explanationContainer = document.getElementById("explanation-container");
      explanationContainer.innerHTML = `
        <p><strong>あなたの答え:</strong> ${selectedChoice}</p>
        <p><strong>正解:</strong> ${currentQuestion.correct}</p>
        <p>${currentQuestion.explanation}</p>
      `;
      explanationContainer.style.display = 'block';
      explanationContainer.className = isCorrect ? 'explanation-box correct' : 'explanation-box incorrect';
      
      // 次へボタンを表示
      const nextButton = document.getElementById("next-button");
      const showResultsButton = document.getElementById("show-results-button");

      if (currentQuestionIndex < quizData.length - 1) {
        nextButton.style.display = 'inline-block';
        nextButton.onclick = () => {
          currentQuestionIndex++;
          renderQuestion();
        };
      } else {
        showResultsButton.style.display = 'inline-block';
        showResultsButton.onclick = endQuiz;
      }
    }

    function endQuiz() {
      clearInterval(timerInterval);
      const endTime = new Date().getTime();
      const totalTime = Math.floor((endTime - startTime) / 1000);

      // 結果データをlocalStorageに保存
      localStorage.setItem("quizResults", JSON.stringify({ quizData, answers: userAnswers.map(a => a.userAnswer), totalTime }));
      
      // 結果ページへ遷移
      location.href = "kaisetu-1.html";
    }

    // ページの読み込みが完了したらクイズを開始
    loadCSV();
  </script>
</body>
</html>