建立测验-有效,但仅适用于第一个问题

时间:2018-09-25 20:40:38

标签: javascript jquery

我正在使用JQuery构建测验游戏。我的游戏可以按照我目前希望的方式运行,但仅限于第一个问题。

var progress = 0;
var score = 0;

var running = true;

var questions = [
  {question: 'Which character is played by Robert Downey Junior?', answers: ['Thor', 'Iron Man', 'Captain America', 'Star Lord'], correct: 'Iron Man'},
  {question: 'What colour is the star on Captain Americas shield?', answers: ['Red', 'Silver/Grey', 'Blue', 'Yellow/Gold'], correct: 'Silver/Grey'}
];

var $quiz = $('.quiz');
var $question = $('#quiz-question');
var $answers = $('#answers');
var $next = $('#next');
var $results = $('#results');

var showQuestion = q => {
  if (progress < questions.length) {
    $question.html(q.question);
    $answers.html(' ');
    q.answers.forEach(function(ans) {
      $answers.append("<div class='answer'>" + ans + "</div>");
    })
  } else {
    $results.html("<h2>Your Results:</h2><p>You scored " + score + "/" + questions.length + "</p>");
    $quiz.hide();
    $results.show();
  }
};

showQuestion(questions[progress]);

$(document).ready(function(){
  $next.hide();
  $results.hide();

  $('.answer').on('click', function(){
    if($(this).html() === questions[progress].correct && running) {
      progress++;
      running = false;
      score++;
      $(this).css('color', 'green');
      $(this).css('border', '3px solid green');
      $(this).css('font-weight', 'bold');
      $next.show();
    } else if ($(this).html() !== questions[progress] && running) {
      $(this).css('color', 'red');
      $(this).css('border', '3px solid red');
      $(this).css('font-weight', 'bold');
      progress++;
      running = false;
      $next.show();
    }
  })

  $next.on('click', function() {
    running = true;
    showQuestion(questions[progress]);
  })
})
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body {
  background-color: #c7ecee;
  font-family: 'Karla', sans-serif;
}

main {
  min-height: 500px;
  width: 100%;
  display: flex;
  align-items: flex-end;
}

main .quiz {
  width: 40%;
  margin: 0 auto;
  text-align: center;
}

main .quiz #quiz-question {
  font-size: 2rem;
  width: 100%;
  border: 2px solid #4d4d4d;
  color: #fff;
  background-color: #4d4d4d;
  padding: 1rem;
}

main .quiz #answers {
  font-size: 1.5rem;
  border: 1px solid #4d4d4d;
}

main .quiz #answers .answer {
  width: 100%;
  padding: 1rem;
  background-color: #fff;
  border: 1px solid #4d4d4d;
  cursor: pointer;
}

main .quiz #answers .answer:hover {

}

div#ui {
  text-align: center;
  width: 100%;
  padding: .75rem;
}

div#ui button {
  font-size: 1.75rem;
  padding: .75rem;
  background-color: #4d4d4d;
  border: 1px solid #4d4d4d;
  color: #fff;
  cursor: pointer;
}
  <main>
    <div class='quiz'>
      <div id='quiz-question'>
      </div>
      <div id='answers'>
      </div>
    </div>
    <div id='results'>
    </div>
  </main>

  <div id='ui'>
    <button id='next'>Next</button>
  </div>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

基本上,将显示一个问题及其答案,单击该答案将停止运行游戏,因此无法单击其他答案(或者不能多次单击一个答案以提高得分)。回答问题后,底部将显示一个按钮,转到下一个问题。如果没有其他问题,它将显示结果显示。

这完全符合我的意愿-一个问题。当我添加任何其他问题时,它将完全按原样显示该问题,但是不再应用单击效果。我假设这与调用$(document).ready()函数时不存在的元素有关。谁能阐明我如何解决这个问题?

已编辑以包含代码段。取消第二个任务的注释

2 个答案:

答案 0 :(得分:1)

在第37行,更改:

$('.answer').on('click', function(){

 $('body').on('click', '.answer', function(){

问题是,当您编写时:

$(document).ready(function(){
    $next.hide();
    $results.hide();

    $('.answer').on('click', function(){

您(当前)定位所有具有类.answer的元素。由于这只是开始时的第一个问题,因此对第一个问题之后的问题将无效。

如果您改写:

$(document).ready(function(){
    $next.hide();
    $results.hide();

    $('body').on('click', '.answer', function(){

您告诉jQuery将click事件添加到将与类.answer(在body元素内)添加的任何当前元素和新元素中。最好保持具体,例如,为测验提供一个ID。

整个示例:

var progress = 0;
var score = 0;

var running = true;

var questions = [
  {question: 'Which character is played by Robert Downey Junior?', answers: ['Thor', 'Iron Man', 'Captain America', 'Star Lord'], correct: 'Iron Man'},
  {question: 'What colour is the star on Captain Americas shield?', answers: ['Red', 'Silver/Grey', 'Blue', 'Yellow/Gold'], correct: 'Silver/Grey'}
];

var $quiz = $('.quiz');
var $question = $('#quiz-question');
var $answers = $('#answers');
var $next = $('#next');
var $results = $('#results');

var showQuestion = q => {
  if (progress < questions.length) {
    $question.html(q.question);
    $answers.html(' ');
    q.answers.forEach(function(ans) {
      $answers.append("<div class='answer'>" + ans + "</div>");
    })
  } else {
    $results.html("<h2>Your Results:</h2><p>You scored " + score + "/" + questions.length + "</p>");
    $quiz.hide();
    $results.show();
  }
};

showQuestion(questions[progress]);

$(document).ready(function(){
  $next.hide();
  $results.hide();

  $('body').on('click', '.answer', function(){
    if($(this).html() === questions[progress].correct && running) {
      progress++;
      running = false;
      score++;
      $(this).css('color', 'green');
      $(this).css('border', '3px solid green');
      $(this).css('font-weight', 'bold');
      $next.show();
    } else if ($(this).html() !== questions[progress] && running) {
      $(this).css('color', 'red');
      $(this).css('border', '3px solid red');
      $(this).css('font-weight', 'bold');
      progress++;
      running = false;
      $next.show();
    }
  })

  $next.on('click', function() {
    running = true;
    showQuestion(questions[progress]);
  })
})
<body>
  <main>
    <div class='quiz'>
      <div id='quiz-question'>
      </div>
      <div id='answers'>
      </div>
    </div>
    <div id='results'>
    </div>
  </main>

  <div id='ui'>
    <button id='next'>Next</button>
  </div>

  <script src='https://code.jquery.com/jquery-3.2.1.min.js' integrity='sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=' crossorigin='anonymous'></script>
  <script src='includes/js/main.js'></script>
</body>

答案 1 :(得分:1)

这是使代码正常工作的最小编辑:

var progress = 0;
var score = 0;

var running = true;

var questions = [
  {question: 'Which character is played by Robert Downey Junior?', answers: ['Thor', 'Iron Man', 'Captain America', 'Star Lord'], correct: 'Iron Man'},
  {question: 'What colour is the star on Captain Americas shield?', answers: ['Red', 'Silver/Grey', 'Blue', 'Yellow/Gold'], correct: 'Silver/Grey'}
];

var $quiz = $('.quiz');
var $question = $('#quiz-question');
var $answers = $('#answers');
var $next = $('#next');
var $results = $('#results');

var showQuestion = q => {
  if (progress < questions.length) {
    $question.html(q.question);
    $answers.html(' ');
    q.answers.forEach(function(ans) {
      $answers.append("<div class='answer'>" + ans + "</div>");
    })

    $('.answer').on('click', function(){
      if($(this).html() === questions[progress].correct && running) {
        progress++;
        running = false;
        score++;
        $(this).css('color', 'green');
        $(this).css('border', '3px solid green');
        $(this).css('font-weight', 'bold');
        $next.show();
      } else if ($(this).html() !== questions[progress] && running) {
        $(this).css('color', 'red');
        $(this).css('border', '3px solid red');
        $(this).css('font-weight', 'bold');
        progress++;
        running = false;
        $next.show();
      }
    })
  } else {
    $results.html("<h2>Your Results:</h2><p>You scored " + score + "/" + questions.length + "</p>");
    $quiz.hide();
    $results.show();
  }
};

showQuestion(questions[progress]);

$(document).ready(function(){
  $next.hide();
  $results.hide();

  $next.on('click', function() {
    running = true;
    showQuestion(questions[progress]);
  })
})
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body {
  background-color: #c7ecee;
  font-family: 'Karla', sans-serif;
}

main {
  min-height: 500px;
  width: 100%;
  display: flex;
  align-items: flex-end;
}

main .quiz {
  width: 40%;
  margin: 0 auto;
  text-align: center;
}

main .quiz #quiz-question {
  font-size: 2rem;
  width: 100%;
  border: 2px solid #4d4d4d;
  color: #fff;
  background-color: #4d4d4d;
  padding: 1rem;
}

main .quiz #answers {
  font-size: 1.5rem;
  border: 1px solid #4d4d4d;
}

main .quiz #answers .answer {
  width: 100%;
  padding: 1rem;
  background-color: #fff;
  border: 1px solid #4d4d4d;
  cursor: pointer;
}

main .quiz #answers .answer:hover {

}

div#ui {
  text-align: center;
  width: 100%;
  padding: .75rem;
}

div#ui button {
  font-size: 1.75rem;
  padding: .75rem;
  background-color: #4d4d4d;
  border: 1px solid #4d4d4d;
  color: #fff;
  cursor: pointer;
}
<main>
    <div class='quiz'>
      <div id='quiz-question'>
      </div>
      <div id='answers'>
      </div>
    </div>
    <div id='results'>
    </div>
  </main>

  <div id='ui'>
    <button id='next'>Next</button>
  </div>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

基本上,您将事件监听器附加到.answer元素一次,然后替换了这些元素,这意味着当用户单击新元素时,什么也没有发生。在这里,我们每次创建问题时都会添加侦听器。

请记住,有多种方法可以重构此代码。如果您要避免为每个.answer元素创建侦听器,我将研究事件委托。