javascript JS测验:正确答案识别问题

lokaqttq  于 2022-12-17  发布在  Java
关注(0)|答案(1)|浏览(141)

我正在开发一个小型的JavaScript测验来练习语言,并将一个项目添加到我的投资组合中。
到目前为止,我已经成功地实现了随机问题和选择,一个计时器,一个进度条和一个分数计数器。
然而,我一直无法让我的代码识别用户提交的选项,该选项应该注册为正确并亮起绿色。作为一种修复,我尝试将答案放入单独的数组中,并让代码通过将答案选项与所述答案数组进行匹配来检查正确性。这导致我的代码将所有用户输入识别为不正确。
下面是我的项目的一个可运行的例子。你会注意到选项仍然是亮绿色或红色的,但是它们没有考虑到随机选择,因此错误地通知用户他们的成功。为了实用起见,我淡化了CSS和HTML方面,并将问题对象减少到3项。
我真的很感激在这方面的一些建议。感谢您的时间,我期待着了解我如何才能解决这个问题。

const question = document.querySelector('#question');
const choices = Array.from(document.querySelectorAll('.choice-text'));
const progressText = document.querySelector('#progressText');
const scoreText = document.querySelector('#score');
const progressBarFull = document.querySelector('#progressBarFull');
const SCORE_POINTS = 10;
const MAX_QUESTIONS = 3;

let currentQuestion = {};
let acceptingAnswers = true;
let score = 0;
let questionCounter = 0;
let availableQuestions = [];

/* Object containing the questions of the quiz game. */
let questions = [{
    question: 'According to Roman mythology, who was the father of Romulus and Remus?',
    choice1: 'A wolf',
    choice2: 'King Numitor',
    choice3: 'Jupiter',
    choice4: 'Mars',
    answer: 4,
  },
  {
    question: 'Which was the first Roman road?',
    choice1: 'Via Egnatia',
    choice2: 'Via Valeria',
    choice3: 'Via Appia',
    choice4: 'Via Flaminia',
    answer: 3,
  },
  {
    question: 'Which of the following did not defeat Mithridates VI of Pontus?',
    choice1: 'Lucullus',
    choice2: 'Marius',
    choice3: 'Pompey',
    choice4: 'Sulla',
    answer: 2,
  }
]

// Start game by setting default hud values
function startGame() {
  questionCounter = 0;
  score = 0;
  availableQuestions = [...questions]; /* Spread operator */
  getNewQuestion()
}

//Randomize question choices
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]];
  }
}

//Get new question and increment the question counter
getNewQuestion = () => {
  if (availableQuestions.length === 0 || questionCounter >= MAX_QUESTIONS) {
    localStorage.setItem('mostRecentScore', score);

    return window.location.assign('index.html') /* Take player to end game*/
  }

  questionCounter++;

  const questionsIndex = Math.floor(Math.random() * availableQuestions.length);
  currentQuestion = availableQuestions[questionsIndex];
  question.innerText = currentQuestion.question;

  //Locate choices
  const answerChoices = [
    currentQuestion.choice1,
    currentQuestion.choice2,
    currentQuestion.choice3,
    currentQuestion.choice4,
  ];

  //Call randomize choices function
  shuffle(answerChoices);

  //Display randomized choices  
  choices.forEach((choice, index) => {
    choice.innerHTML = answerChoices[index];
  });

  availableQuestions.splice(questionsIndex, 1);

  acceptingAnswers = true;
}

//Check answer if correct (Currently can't detect the right answer in randomized choices)
choices.forEach(choice => {
  choice.addEventListener('click', e => {
    if (!acceptingAnswers) return

    acceptingAnswers = false;
    const selectedChoice = e.target;
    const selectedAnswer = selectedChoice.dataset['number'];

    let classToApply = selectedAnswer == currentQuestion.answer ? 'correct' : 'incorrect';

    if (classToApply === 'correct') {
      incrementScore(SCORE_POINTS);
    }

    selectedChoice.parentElement.classList.add(classToApply);

    setTimeout(() => {
      selectedChoice.parentElement.classList.remove(classToApply);
      getNewQuestion();
    }, 1000);
  })
})

incrementScore = num => {
  score += num;
  scoreText.innerText = score;
}

startGame()
.choice-container {
  color: var(--basic-black);
  display: flex;
  margin-bottom: 1rem;
  width: 100%;
  border-radius: 4px;
  background-color: var(--honey-yellow);
  font-size: 3rem;
  min-width: 40rem;
}

.choice-prefix {
  padding: 1.5rem 1.5rem;
  color: var(--basic-black);
}

.correct {
  background: green;
}

.incorrect {
  background: red;
}
<div id="game" class="justify-center flex-column">
  <div id="hud">
    <div class="hud-item">
      <p id="progressText" class="hud-prefix">
        Question
      </p>
      <div id="progressBar">
        <div id="progressBarFull"></div>
      </div>
    </div>
    <div class="hud-item">
      <p class="hud-prefix">
        Score
      </p>
      <h1 class="hud-main-text" id="score">
        0
      </h1>
    </div>
  </div>
  <h1 id="question">Sample Question?</h1>
  <div class="choice-container">
    <p class="choice-prefix">I.</p>
    <p class="choice-text" data-number="1">Choice 1</p>
  </div>
  <div class="choice-container">
    <p class="choice-prefix">II.</p>
    <p class="choice-text" data-number="2">Choice 2</p>
  </div>
  <div class="choice-container">
    <p class="choice-prefix">III.</p>
    <p class="choice-text" data-number="3">Choice 3</p>
  </div>
  <div class="choice-container">
    <p class="choice-prefix">IV.</p>
    <p class="choice-text" data-number="4">Choice 4</p>
  </div>
</div>
ttcibm8c

ttcibm8c1#

代码还有更大的改进空间,但OP的bug源于标记中的data-number是一个字符串,而问题对象的答案是由一个int表示的。通过转换一个或另一个来修复。
查看代码段中的注解...

const question = document.querySelector('#question');
const choices = Array.from(document.querySelectorAll('.choice-text'));
const progressText = document.querySelector('#progressText');
const scoreText = document.querySelector('#score');
const progressBarFull = document.querySelector('#progressBarFull');
const SCORE_POINTS = 10;
const MAX_QUESTIONS = 3;

let currentQuestion = {};
let acceptingAnswers = true;
let score = 0;
let questionCounter = 0;
let availableQuestions = [];

/* Object containing the questions of the quiz game. */
let questions = [{
    question: 'According to Roman mythology, who was the father of Romulus and Remus?',
    choice1: 'A wolf',
    choice2: 'King Numitor',
    choice3: 'Jupiter',
    choice4: 'Mars',
    answer: 4,
  },
  {
    question: 'Which was the first Roman road?',
    choice1: 'Via Egnatia',
    choice2: 'Via Valeria',
    choice3: 'Via Appia',
    choice4: 'Via Flaminia',
    answer: 3,
  },
  {
    question: 'Which of the following did not defeat Mithridates VI of Pontus?',
    choice1: 'Lucullus',
    choice2: 'Marius',
    choice3: 'Pompey',
    choice4: 'Sulla',
    answer: 2,
  }
]

// Start game by setting default hud values
function startGame() {
  questionCounter = 0;
  score = 0;
  availableQuestions = [...questions]; /* Spread operator */
  getNewQuestion()
}

//Randomize question choices
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]];
  }
}

//Get new question and increment the question counter
getNewQuestion = () => {
  if (availableQuestions.length === 0 || questionCounter >= MAX_QUESTIONS) {
    localStorage.setItem('mostRecentScore', score);

    return window.location.assign('index.html') /* Take player to end game*/
  }

  questionCounter++;

  const questionsIndex = Math.floor(Math.random() * availableQuestions.length);
  currentQuestion = availableQuestions[questionsIndex];
  question.innerText = currentQuestion.question;

  //Locate choices
  const answerChoices = [
    currentQuestion.choice1,
    currentQuestion.choice2,
    currentQuestion.choice3,
    currentQuestion.choice4,
  ];

  //Call randomize choices function
  shuffle(answerChoices);

  //Display randomized choices  
  choices.forEach((choice, index) => {
    choice.innerHTML = answerChoices[index];
  });

  availableQuestions.splice(questionsIndex, 1);

  acceptingAnswers = true;
}

//Check answer if correct (Currently can't detect the right answer in randomized choices)
choices.forEach(choice => {
  choice.addEventListener('click', e => {
    if (!acceptingAnswers) return

    acceptingAnswers = false;
    const selectedChoice = e.target;

    // HERE: the + sign coerces the string from the markup into an int
    const selectedAnswer = +selectedChoice.dataset['number'];

    let classToApply = selectedAnswer == currentQuestion.answer ? 'correct' : 'incorrect';

    if (classToApply === 'correct') {
      incrementScore(SCORE_POINTS);
    }

    selectedChoice.parentElement.classList.add(classToApply);

    setTimeout(() => {
      selectedChoice.parentElement.classList.remove(classToApply);
      getNewQuestion();
    }, 1000);
  })
})

incrementScore = num => {
  score += num;
  scoreText.innerText = score;
}

startGame()
.choice-container {
  color: var(--basic-black);
  display: flex;
  margin-bottom: 1rem;
  width: 100%;
  border-radius: 4px;
  background-color: var(--honey-yellow);
  font-size: 3rem;
  min-width: 40rem;
}

.choice-prefix {
  padding: 1.5rem 1.5rem;
  color: var(--basic-black);
}

.correct {
  background: green;
}

.incorrect {
  background: red;
}
<div id="game" class="justify-center flex-column">
  <div id="hud">
    <div class="hud-item">
      <p id="progressText" class="hud-prefix">
        Question
      </p>
      <div id="progressBar">
        <div id="progressBarFull"></div>
      </div>
    </div>
    <div class="hud-item">
      <p class="hud-prefix">
        Score
      </p>
      <h1 class="hud-main-text" id="score">
        0
      </h1>
    </div>
  </div>
  <h1 id="question">Sample Question?</h1>
  <div class="choice-container">
    <p class="choice-prefix">I.</p>
    <p class="choice-text" data-number="1">Choice 1</p>
  </div>
  <div class="choice-container">
    <p class="choice-prefix">II.</p>
    <p class="choice-text" data-number="2">Choice 2</p>
  </div>
  <div class="choice-container">
    <p class="choice-prefix">III.</p>
    <p class="choice-text" data-number="3">Choice 3</p>
  </div>
  <div class="choice-container">
    <p class="choice-prefix">IV.</p>
    <p class="choice-text" data-number="4">Choice 4</p>
  </div>
</div>

相关问题