2016-10-17 2 views
1

Ich versuche Javascript zu lernen, indem ich eine Quiz-App wie die hier erwähnte erstellen: Learn Javascript Properly Ich habe Probleme, den fortgeschritteneren Quiz zu machen, ich benutze Lenker als meine Template-Engine. Ich habe die Fragen in einer externen JSON-Datei gespeichert und die Eingaben sind nur ein paar Optionsfelder.Nummer nicht richtig inkrementieren

index.html:

<!DOCTYPE html> 
<html> 
<head> 
    <title>Quiz Application</title> 
    <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet"> 
    <link rel="stylesheet" type="text/css" href="style.css"> 
</head> 
<body> 
<div id="container"> 
    <div id="quiz"> 
    </div> 
    <button id="next-question">Next Question</button> 
</div> 

<!-- Templates --> 
<script id="titleTemplate" type="text/x-handlebars-template"> 
    <div id="quiz-question">{{ title }}</div> 
</script> 
<script id="choicesTemplate" type="text/x-handlebars-template"> 
    <div id="choices"> 
     <form id="choicesForm"> 
       {{#each choices}} 
       <div class="choice"> 
        <input type="radio" name="choices" id="choice{{@index}}" value="{{ @index }}"> 
        <label for="choice{{ @index }}" value="{{ @index }}">{{ this }}</label> 
       </div> 
       {{/each}} 
     </form> 
    </div> 
</script> 

<script type="text/javascript" src="js/jquery-3.1.0.js"></script> 
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.js"></script> 
<script type="text/javascript" src="js/app.js"></script> 
</body> 
</html> 

Ich habe alles in den Kommentaren erklärt app.js:

"use strict"; 
var Render = { 
    question: function(questions, currentIndex) { 
     var titleTemplate = Handlebars.compile($("#titleTemplate").html()); 
     var choicesTemplate = Handlebars.compile($("#choicesTemplate").html()); 
     var currentQuestion = questions[currentIndex]; 
     Render.title(titleTemplate, currentQuestion); 
     Render.choices(choicesTemplate, currentQuestion); 
    }, 
    title: function(titleTemplate, currentQuestion) { 
     $("#quiz").html(titleTemplate(currentQuestion)); 
    }, 
    choices: function(choicesTemplate, currentQuestion) { 
     $('#quiz-question').append(choicesTemplate(currentQuestion)); 
    }, 
}; 

var Quiz = { 
    // Tracks the current questions 
    currentIndex: 0, 

    // The number of the correct answers 
    // I want to increment this when the user 
    // answers the correct question, for some reason it doesn't increment. 
    correctAnswers: 0, 

    // I first call this method to get the questions from JSON file 
    // since you can no longer have synchronous requests 
    getQuestions: function() { 
     $.getJSON('questions.json', Quiz.start); 
    }, 
    // Starts the quiz 
    start: function(questions) { 
     // Check if the user is passed the last question 
     // in this case, if 6 > 5 
     if(Quiz.currentIndex + 1 > questions.length) { 
      Quiz.displayFinalScore(questions); 
     } else { 
      // Render the next question using the currentIndex 
      Render.question(questions, Quiz.currentIndex); 
      Quiz.handleQuestion(questions);  
     } 
    }, 

    handleQuestion: function(questions) { 
     // Get's the correct answer from the JSON 
     var correctAnswer = questions[Quiz.currentIndex].correctAnswer; 
     // Check if the radio button is checked 
     if($("input[name=choices]:checked", "#choicesForm") == correctAnswer) { 
      // This doesn't increment like it suppose to 
      // It still stays at 0. 
      Quiz.correctAnswers += 1; 
     } 

     // Increment the index to change to the next question 
     Quiz.currentIndex += 1; 
    }, 
    displayFinalScore: function(questions) { 
     // Simple console log 
     console.log("You have scored: " + Quiz.correctAnswers + " out of " + questions.length); 
    } 
}; 

$(function() { 
    Quiz.getQuestions();  
    $("#next-question").on("click", Quiz.getQuestions); 
}) 

Wie Sie sehen können habe ich in den Kommentaren erklärt Das Problem besteht darin, die correctAnswers aus irgendeinem Grund inkrementieren, es kommt nicht an den Punkt, wo es beide Variablen vergleicht, auch wenn ich die richtige Antwort wähle von den Radioknöpfen.

questions.json:

[ 
    { 
     "title":"When did the programming language C++ came out?", 
     "choices":[ 
      1997, 
      1995, 
      2000, 
      1998 
     ], 
     "correctAnswer":3 
    }, 
    { 
     "title":"When Node.js came out?", 
     "choices":[ 
      2010, 
      2011, 
      2009, 
      2006 
     ], 
     "correctAnswer":2 
    }, 
    { 
     "title":"What brand of laptop do I have?", 
     "choices":[ 
      "HP", 
      "Acer", 
      "Dell", 
      "Lenovo" 
     ], 
     "correctAnswer":0 
    }, 
    { 
     "title":"How old am I?", 
     "choices":[ 
      12, 
      20, 
      9, 
      16 
     ], 
     "correctAnswer":3 
    }, 
    { 
     "title":"How old is Google?", 
     "choices":[ 
      12, 
      20, 
      18, 
      16 
     ], 
     "correctAnswer":2 
    } 
] 
+0

parse es zu int oder float um zu inkrementieren – guradio

+0

Ich tat das auch, immer noch nicht funktioniert. – Akar

+0

können Sie eine einfache Demo erstellen, die Ihr Problem zeigt? – guradio

Antwort

1

Es gibt einige Probleme mit Ihrem Code und sie sind:

  • In der start Funktion sollten Sie if Bedingungsausdruck ändern Array-Indizes zu entsprechen, die in JavaScript sind ab 0 und das letzte Element des Arrays haben Index questions.length - 1.
  • In der start Funktion rendern Sie zunächst eine neue Frage und fragen dann DOM nach dem ausgewählten Element ab, das in dieser Phase bereits zerstört ist. Also musst du zuerst handleQuestion und erst dann neu rendern.
  • zog ich auch currentIndex Schritt Code zum letzten Schritt (nach dem Rendern)
  • Da handleQuestion nicht beim ersten Render ausgeführt werden soll, habe ich diese exotischen Quiz.currentIndex && Quiz.handleQuestion(questions);, die eigentlich bedeutet: „Wenn currentIndex 0, die in boolean Ausdrücke transformiert in false, führen Sie nicht den rechten Teil der booleschen Bedingung, die Quiz.handleQuestion(questions) ist ".
  • Um einen numerischen Wert von ausgewähltem Eingang zu holen, sollten Sie parseInt($("input[name=choices]:checked", "#choicesForm").val(), 10)

Der resultierende Code verwenden soll wie folgt aussehen:

JavaScript

// Starts the quiz 
start: function(questions) { 
    // Check if the user is passed the last question 
    // in this case, if 5 >= 5 
    if(Quiz.currentIndex >= questions.length) { 
     Quiz.displayFinalScore(questions); 
    } else { 
     Quiz.currentIndex && Quiz.handleQuestion(questions); 
     // Render the next question using the currentIndex 
     Render.question(questions, Quiz.currentIndex++); 
    } 
}, 

handleQuestion: function(questions) { 
    // Get's the correct answer from the JSON 
    var correctAnswer = questions[Quiz.currentIndex-1].correctAnswer; 
    // Check if the radio button is checked 
    if(parseInt($("input[name=choices]:checked", "#choicesForm").val(), 10) === correctAnswer) { 
     // This doesn't increment like it suppose to 
     // It still stays at 0. 
     Quiz.correctAnswers += 1; 
    } 
} 

Live Demo

https://plnkr.co/edit/03IGvb6IZiw6QbziUpw6?p=preview

+0

Schöne Antwort, aber es zählt immer noch nicht die letzte Antwort. Also selbst wenn ich alle Fragen richtig beantworte, wäre das Ergebnis 4 von 5 Punkten. Aber immer noch haben Sie die meisten Probleme gelöst, danke! – Akar

Verwandte Themen