You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript表单无法保存答案问题排查求助

修复测验表单的答案保存与状态恢复问题

需求与问题

需求:

  • 保存用户答题结果,点击「返回」按钮时高亮显示之前选择的选项
  • 根据用户答对的题目数量跳转至对应页面

当前存在的问题:

  • 答案完全无法保存,console.log仅能记录第一题的答案
  • 点击「返回」按钮后,所有题目选中状态一致

问题根源分析

  1. 单选框元素未动态更新:表单里的单选框始终使用q1作为name属性,切换到后续题目时,没有生成对应q2、q3的单选框,导致所有题目共用同一组单选框,状态混乱。
  2. CSS选择器语法错误:恢复选中状态时使用了错误的选择器input[name="qX"]:[value="Y"],多了一个不必要的冒号,导致无法正确定位单选框。
  3. 答案存储与读取逻辑不匹配:切换题目时没有同步更新表单内的单选框结构,导致读取之前保存的答案时无法找到对应元素。

修复后的完整代码

<style>
/* CSS Styles for the quiz - Customize as needed */

/* Styling for the quiz container */
#quizContainer {
  padding: 20px;
  border-radius: 10px;
  max-width: 600px; /* Set a maximum width */
  margin: 0 auto; /* Center the container */
}

/* Styling for the title and subtitle */
#titleContainer {
  background-color: #dfedef; /* Background color for title and subtitle */
  padding: 5px 20px; /* Added top and bottom padding */
  border-radius: 10px;
  margin-bottom: 20px;
  text-align: center; /* Center align the text */
}

/* Styling for the question number and question */
#questionContainer {
  background-color: #fcfaf7; /* Background color */
  padding: 10px; /* Added padding */
  border-radius: 10px; /* Added border radius */
  margin-bottom: 20px; /* Added margin */
}

/* Styling for the title */
h1 {
  font-size: 1.2em; /* Half the original size */
  margin-top: 0;
  margin-bottom: 0;
  color: #2d536a; /* Changed title color */
}
#age {
  font-size: 0.8em; /* 3/4 of the current size */
  font-weight: bold;
  color: #b95966; /* Color for "15-18 meses" */
  margin-top: 0;
}

/* Styling for Yes/No buttons */
input[type="radio"] {
  display: none; /* Hide default radio buttons */
}
label.btn {
  display: inline-block;
  margin: 5px;
  padding: 6px 16px; /* Adjusted padding */
  border: 1px solid #2d536a; /* Changed outline color */
  border-radius: 5px; /* Adding border radius */
  cursor: pointer;
  transition: background-color 0.3s ease, color 0.3s ease;
}
input[type="radio"]:checked+label.btn {
  background-color: #63a3ad; /* Changed background color when selected */
  color: white; /* Changed text color */
}

/* Styling for Previous/Next buttons */
#prevBtn,
#nextBtn {
  display: inline-block;
  margin-top: 45px; /* Increased margin */
  margin-right: 10px;
  padding: 6px 16px; /* Adjusted padding */
  background-color: #63a3ad; /* Changed background color */
  color: white; /* Changed text color */
  border: none; /* Removed outline */
  border-radius: 5px; /* Adding border radius */
  cursor: pointer;
  transition: background-color 0.3s ease, color 0.3s ease;
  font-size: 20px; /* Adjusting font size */
  vertical-align: middle; /* Aligns buttons vertically */
}
</style>

<div id="quizContainer">
  <div id="titleContainer">
    <h1>Hitos del lenguaje<br><span id="age">15-18 meses</span></h1>
  </div>
  <div id="questionContainer">
    <p><strong>Question 1:</strong><br>Is the sky blue?</p>
  </div>
  <form id="quizForm">
    <div id="answerContainer">
      <!-- 单选框将通过JS动态生成 -->
    </div>
    <button type="button" id="prevBtn">&larr;</button> <!-- Left arrow character -->
    <button type="button" id="nextBtn">&rarr;</button> <!-- Right arrow character -->
  </form>
</div>

<script>
document.addEventListener('DOMContentLoaded', function() {
  let questionNumber = 1;
  // 定义正确答案,用于后续计算得分
  const correctAnswers = {
    1: "yes",
    2: "yes",
    3: "no",
    4: "yes"
  };
  const questions = [
    "Is the sky blue?",
    "Do you like pizza?",
    "Have you traveled abroad?",
    "Do you enjoy reading?"
  ];
  const selectedAnswers = {}; // 存储用户选择的答案
  const answerContainer = document.getElementById('answerContainer');

  // 初始化第一题的单选框
  renderAnswerOptions(questionNumber);
  // 初始隐藏返回按钮
  document.getElementById('prevBtn').style.display = 'none';

  // 渲染对应题目的单选框选项
  function renderAnswerOptions(qNum) {
    // 清空容器并生成新的单选框
    answerContainer.innerHTML = `
      <input type="radio" id="yes${qNum}" name="q${qNum}" value="yes">
      <label for="yes${qNum}" class="btn">Yes</label>
      <input type="radio" id="no${qNum}" name="q${qNum}" value="no">
      <label for="no${qNum}" class="btn">No</label>
    `;
    // 恢复之前选中的答案
    const selected = selectedAnswers[qNum];
    if (selected) {
      document.querySelector(`input[name="q${qNum}"][value="${selected}"]`).checked = true;
    } else {
      // 无选中状态时清空
      document.querySelectorAll(`input[name="q${qNum}"]`).forEach(radio => radio.checked = false);
    }
  }

  document.getElementById('nextBtn').addEventListener('click', function() {
    // 保存当前题目的答案
    const answer = document.querySelector(`input[name="q${questionNumber}"]:checked`);
    if (answer) {
      selectedAnswers[questionNumber] = answer.value;
    }

    if (questionNumber < questions.length) {
      questionNumber++;
      // 更新题目文本
      document.getElementById('questionContainer').innerHTML = `<p><strong>Question ${questionNumber}:</strong><br>${questions[questionNumber - 1]}</p>`;
      // 渲染当前题目的单选框
      renderAnswerOptions(questionNumber);
      // 显示返回按钮
      document.getElementById('prevBtn').style.display = 'inline-block';
      // 切换按钮文本
      if (questionNumber === questions.length) {
        document.getElementById('nextBtn').innerText = 'See Results';
      }
    } else {
      // 计算答对数量
      let correctCount = 0;
      Object.keys(correctAnswers).forEach(qNum => {
        if (selectedAnswers[qNum] === correctAnswers[qNum]) {
          correctCount++;
        }
      });
      console.log(`答对题目数量:${correctCount}`);
      // 根据得分跳转页面,示例:
      if (correctCount === 4) {
        // window.location.href = 'perfect-score.html';
        alert('全部答对!跳转至满分页面');
      } else if (correctCount >= 2) {
        // window.location.href = 'good-score.html';
        alert('答对一半以上,跳转至良好页面');
      } else {
        // window.location.href = 'low-score.html';
        alert('答对较少,跳转至基础页面');
      }
    }
  });
  
  document.getElementById('prevBtn').addEventListener('click', function() {
    if (questionNumber > 1) {
      // 保存当前题目的答案
      const answer = document.querySelector(`input[name="q${questionNumber}"]:checked`);
      if (answer) {
        selectedAnswers[questionNumber] = answer.value;
      }
      
      questionNumber--;
      // 更新题目文本
      document.getElementById('questionContainer').innerHTML = `<p><strong>Question ${questionNumber}:</strong><br>${questions[questionNumber - 1]}</p>`;
      // 渲染当前题目的单选框
      renderAnswerOptions(questionNumber);
      // 切换按钮文本
      document.getElementById('nextBtn').innerText = 'Next';
      // 隐藏返回按钮(当回到第一题时)
      if (questionNumber === 1) {
        document.getElementById('prevBtn').style.display = 'none';
      }
    }
  });
});
</script>

关键修复点说明

  1. 动态生成单选框:新增renderAnswerOptions函数,每次切换题目时生成对应qX的单选框,确保每个题目有独立的name和id,避免状态冲突。
  2. 修正选择器语法:将错误的input[name="qX"]:[value="Y"]改为正确的input[name="qX"][value="Y"],能准确定位到目标单选框。
  3. 完善答案保存逻辑:点击「返回」按钮时也会保存当前题目的答案,避免丢失未提交的选择。
  4. 添加得分计算与跳转:新增correctAnswers对象存储正确答案,完成测验后计算答对数量,根据得分执行跳转逻辑(示例用alert展示,可替换为实际跳转代码)。
  5. 优化按钮显示逻辑:第一题时隐藏「返回」按钮,切换到最后一题时「下一步」按钮变为「查看结果」。

内容的提问来源于stack exchange,提问作者Bernardo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 18:22:02