Newer
Older
2025-Otaki / system / phlox-quiz1.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
   <!-- この1行を追加します -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>音の強弱編</title>
  <link rel="stylesheet" href="phlox.css" />
  <style>
    table.quizTable {
      border-collapse: collapse;
      width: 100%;
      margin: 1em auto;
    }

    table.quizTable th,
    table.quizTable td {
      border: 1px solid #ccc;
      padding: 0.6em;
      vertical-align: top;
      text-align: left;
    }

    td.choices {
      text-align: center;
    }

    .radio-group {
      display: flex;
      flex-wrap: wrap;
      gap: 1em;
      justify-content: flex-start;
    }

    .radio-group label {
      display: inline-block;
      min-width: 8em;
    }
  </style>
</head>
<body>
  <h1>ここは音の強弱についてのクイズ</h1>
  <div id="timer" style="font-size: 1.5em; margin-bottom: 1em; text-align: center;">タイム: 00:00</div>
  <form id="quizForm">
    <table class="quizTable" id="quizTable">
      <thead>
        <tr><th>問題</th><th>選択肢</th></tr>
      </thead>
      <tbody></tbody>
    </table>
    <input type="submit" value="送信">
  </form>

  <script>
      // **タイマー関連の変数と関数はスクリプトの先頭にまとめる**
    let startTime;     // クイズが始まった時刻を記録する変数
    let timerInterval; // タイマーを動かし続けるためのIDを記録する変数

    // 1秒ごとにタイマーの表示を更新する関数
    function updateTimer() {
      const currentTime = new Date().getTime(); // 現在時刻(ミリ秒)
      const elapsedTime = Math.floor((currentTime - startTime) / 1000); // 経過時間(秒)

      // 秒を分と秒に変換して、0埋め(例: 5秒なら"05")
      const minutes = String(Math.floor(elapsedTime / 60)).padStart(2, '0');
      const seconds = String(elapsedTime % 60).padStart(2, '0');

      // HTMLのタイマー表示部分を更新
      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() !== "");
      const quizData = [];

      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];
        const shuffledChoices = shuffle([...choices]);

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

      renderQuiz(quizData);

      // **** ここが重要です! ****
      // CSVの読み込みとクイズ表示が終わった後に、タイマーを開始します。
      startTime = new Date().getTime(); // 現在時刻を記録(タイマー開始)
      timerInterval = setInterval(updateTimer, 1000); // 1秒ごとにupdateTimer関数を実行
    } // <-- loadCSV関数の閉じ括弧はここにあります

    function renderQuiz(quizData) {
      const tbody = document.querySelector("#quizTable tbody");
      tbody.innerHTML = "";

      quizData.forEach((q, idx) => {
        const tr = document.createElement("tr");

        const tdQuestion = document.createElement("td");
        tdQuestion.innerHTML = `<strong>Q${idx + 1}</strong> ${q.question}`;

        const tdChoices = document.createElement("td");
        tdChoices.className = "choices";

        const choiceGroup = document.createElement("div");
        choiceGroup.className = "radio-group";

        q.choices.forEach(choice => {
          const label = document.createElement("label");
          label.innerHTML = `<input type="radio" name="q${idx}" value="${choice}"> ${choice}`;
          choiceGroup.appendChild(label);
        });

        tdChoices.appendChild(choiceGroup);
        tr.appendChild(tdQuestion);
        tr.appendChild(tdChoices);
        tbody.appendChild(tr);
      });

      const form = document.getElementById("quizForm");
      form.onsubmit = function (e) {
        e.preventDefault();

        // タイマーを停止する
        clearInterval(timerInterval);
        const endTime = new Date().getTime(); // 送信ボタンが押された時刻を記録
        const totalTime = Math.floor((endTime - startTime) / 1000); // 経過時間(秒)を計算

        const answers = quizData.map((q, idx) => {
          const checked = document.querySelector(`input[name="q${idx}"]:checked`);
          return checked ? checked.value : null;
        });

        // localStorageにtotalTimeも一緒に保存する
        localStorage.setItem("quizResults", JSON.stringify({ quizData, answers, totalTime }));
        location.href = "kaisetu-1.html"; // 解答ページへ遷移
      };
    }

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