【问题标题】:Trying to set an increment controller尝试设置增量控制器
【发布时间】:2019-03-18 09:51:04
【问题描述】:

我正在构建一个简单的琐事应用程序,到目前为止它很棒,但我在继续下一个问题时遇到了问题。 奇怪的是,当用户正确回答问题并按下提交按钮时,它确实会增加到下一个问题,但如果他们再次正确回答,它什么也不做。

这是我的代码:

  <div class="app">
      <h2 id="question"></h2>
          <button class="options" type="button" value="val"></button>
          <button class="options" type="button" value="val"></button>
          <button class="options" type="button" value="val"></button>
          <button class="options" type="button" value="val"></button>
        </br>
            <button id="submit" type="button" name="button">Submit</button>
            <button id="back" type="button" name="button">Back</button>
    </div>



var data = {
  currentQuestion: 0,
  questions:[
    {
      answers:[1,3,5,6],
      question:'how much is 3+3',
      correctAnswer:6
     },
    {
      answers:[1,3,5,2],
      question:'how much is 1+1',
      currectAnswer:2
    },
     {
       answers:[1,8,5,6],
       question:'how much is 4+4',
       correctAnswer:8
     },
     {
       answers:[1,8,10,6],
       question:'how much is 4+6',
       correctAnswer:8
     }
  ]
}


var options = document.querySelectorAll('.options');
var question = document.querySelector('#question');
var backBtn = document.querySelector('#back');
var submitBtn = document.querySelector('#submit');





function init() {
  newQuestion();
  optionClick();
  evaluate();
  back();

}


function newQuestion() {
  question.textContent = data.questions[data.currentQuestion].question;
  for(var i = 0; i< data.questions.length; i++) {
    options[i].textContent = data.questions[data.currentQuestion].answers[i]
  }
}



function optionClick() {
    options.forEach(function(elem) {
      elem.addEventListener('click', function() {
        this.classList.toggle('picked')
      })
    })

}


function evaluate() {
  submitBtn.addEventListener('click', function() {
    for(i = 0; i < options.length; i++) {
      if(options[i].classList.contains('picked') && options[i].textContent == data.questions[data.currentQuestion].correctAnswer && data.currentQuestion <= 6){
        options[i].classList.remove('picked')
        data.currentQuestion++
        newQuestion();
      }
    }
  })
}

【问题讨论】:

  • 另外,我目前正在运行 4 个按钮,它们代表可能的答案中的 4 个选项,它们都共享同一个类,我选择它们作为 querySelectorAll 以将它们定义为一个数组。我还在我的 css 中创建了一个简单的“picked”类来点亮所选答案的边框。我的问题是,是否有办法将切换类选项限制为一次只有一个元素,因此如果我单击另一个选项,那么之前选择的选项将被关闭。提前ty(-:
  • 您遗漏了附加事件的部分,这对于帮助您解决问题可能很重要。 optionClick 是仅在 init 中运行还是在单击选项时运行?现在的方式是,每次optionClick 运行时,它都会为每个按钮重新附加一个新事件。同样,每次evaluate 运行时,它都会将一个新的事件处理程序附加到submitBtn。通常,对于这种东西,您只想在开始时附加一次事件。此外,(相关元素的)实际 HTML 结构可能会有所帮助。 minimal reproducible example
  • 我添加了 HTML。 optionClick 事件是在 init 中设置的,因为它们看起来这个应用程序的方式是你有问题,并且你有 4 个方形按钮,所以当你选择 1 个按钮(答案选项)时,你然后用“提交”提交它按钮,然后进行评估。
  • 如果您仅在“1+1 是多少”问题之后才观察到该问题,可能是因为该对象没有“正确答案”属性。相反,它有一个“currectAnswer”属性,这可能会导致问题。
  • 我想把这个optionClick事件函数分开,使其模块化

标签: javascript increment ecmascript-5


【解决方案1】:

正如 cmets 中已经回答的那样,问题是一个错字,currectAnswer 而不是correctAnswer。现在回答有点没有实际意义,但我还想提出一些其他改进建议。

我要做的第一件事是使用一组单选按钮,而不是使用一组按钮。如果您愿意,您可以将它们设置为看起来像一个按钮,并且您可以通过这样做获得免费的功能。单选按钮强制只选择一个答案,而无需检查代码中的多个答案。

不要使用在调用时附加匿名函数作为事件处理程序的命名函数,只需创建一个命名函数,然后将它们直接附加到元素。

把它放在一起看起来像这样:

'use strict';
var data = {
  currentQuestion: 0,
  questions:[
    {
      answers:[1,3,5,6],
      question:'how much is 3+3',
      correctAnswer:6
     },
    {
      answers:[1,3,5,2],
      question:'how much is 1+1',
      correctAnswer:2
    },
     {
       answers:[1,8,5,6],
       question:'how much is 4+4',
       correctAnswer:8
     },
     {
       answers:[1,8,10,6],
       question:'how much is 4+6',
       correctAnswer:10
     }
  ]
}


var options = document.querySelectorAll('#options input');
var question = document.querySelector('#question');
var backBtn = document.querySelector('#back');
var submitBtn = document.querySelector('#submit');

function nextQuestion () {
  if (data.currentQuestion < data.questions.length - 1) {
    data.currentQuestion += 1;
    displayQuestion();
  } else {
    data.currentQuestion = data.questions.length;
    submitBtn.removeEventListener('click', evaluate);
    backBtn.removeEventListener('click', prevQuestion);
    question.textContent = "Done!"
  }
}

function prevQuestion () {
  if (data.currentQuestion > 0) {
    data.currentQuestion -= 1;
    displayQuestion();
  }
}

function displayQuestion () {
  question.textContent = data.questions[data.currentQuestion].question;

  options.forEach(function (option, index) {
    let answer = data.questions[data.currentQuestion].answers[index];
    // set the value of the radio button
    option.value = answer;
    // set the text of the label next to it
    option.nextElementSibling.textContent = answer;
    // reset the selected value
    option.checked = false
  });
}

function evaluate () {
  let correctAnswer = data.questions[data.currentQuestion].correctAnswer;
  // get the value of the currently selected answer
  let selectedAnswer = document.querySelector('#options :checked');

  if(selectedAnswer && selectedAnswer.value == correctAnswer){
    nextQuestion();
  }
}

submitBtn.addEventListener('click', evaluate);
backBtn.addEventListener('click', prevQuestion);
displayQuestion();
  fieldset {
    border: none;
  }

  /* highlight the label immediately after the selected radio button */
  #options input:checked + label {
    border: 3px red solid;
  }

  /* hide the actual radio button 
     that the labels are controling. */
  #options input {
    display: none;
  }

  /* make the label look like a button */
  #options label {
    padding: .5em;
    background: #eee;
    border: outset 1px #eee;
  }
<div class="app">
  <h2 id="question"></h2>
  <fieldset id="options">
    <input id="answer1" type="radio" name="answers"> <label for="answer1"></label>
    <input id="answer2" type="radio" name="answers"> <label for="answer2"></label>
    <input id="answer3" type="radio" name="answers"> <label for="answer3"></label>
    <input id="answer4" type="radio" name="answers"> <label for="answer4"></label>
  </fieldset>

  <button id="submit" type="button" name="button">Submit</button>
  <button id="back" type="button" name="button">Back</button>
</div>

【讨论】:

    猜你喜欢
    • 2023-03-10
    • 2015-03-02
    • 1970-01-01
    • 2012-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多