2016-04-07 7 views
4

Ich versuche, einen Klick durch Persönlichkeit Quiz mit reinem Javascript für eine Uni-Zuordnung zu erstellen. Ich habe eine Reihe von Divs angelegt, damit sie erscheinen können. Jede Frage hat eine Liste von 4 (oder so) Antworten, die sich auf einen anderen Persönlichkeitstyp beziehen. Ich beabsichtige, eine Reihe von Objekten zu behalten, um jede ausgewählte Antwort zu vergleichen und am Ende eine Aufschlüsselung der Persönlichkeitstypen bereitzustellen.Javascript Persönlichkeit Quiz Problem mit 'this' und Daten * Attribute

Ich bin derzeit fest auf die Funktion zu;

  1. Datensatz die ausgewählten Daten und fügen Sie sie in das Array Antworten,
  2. verstecken die aktuelle Frage div und
  3. Display die nächste Frage div

HTML:

<div class="question" id="q1" data-next="q2"> 
    <h2>Question 1:</h2> 
    <p>Which of the following is your favourite movie? </p> 
    <ol class="button"> 
    <li data-score="Ninja">Karate Kid</li> 
    <li data-score="Robot">Wall-E</li> 
    <li data-score="Pirate">Pirates of the Caribbean</li> 
    <li data-score="Zombie">Dawn of the Dead</li> 
    </ol> 
</div> 

<div class="question" id="q2" data-next="q3"> 
    <h2>Question 2:</h2> 
    <p>A building is on fire and you hear a child's screaming for help from the third floor window. Do you: </p> 
    <ol class="button"> 
    <li data-score="Ninja">Mysteriously disappear and re-appear with the children</li> 
    <li data-score="Robot">Run in and save the child on the second floor, because i'm made of metal and fire won't hurt me!</li> 
    <li data-score="Pirate">Dress up as a pirate and loot the surrounding neighbourhood, including the bank?</li> 
    <li data-score="Zombie">Eat all the brains. Nom nom uuuuggghhh.</li> 
    </ol> 
</div> 

JS:

// Create a listener for clicks on the 'start the quiz' button on the front page. 
    document.getElementById("beginquiz").addEventListener("click", startQuiz); 

// When the button is clicked the 'intro' div is hidden and the first question div is displayed 
function startQuiz() { 
    document.getElementById("intro").style.display = "none"; 
    document.getElementById("q1").style.display = "block"; 
} 

// Create an array object to store all the quiz answers. Each selected answer should increase the category score by 1. The highest score will be the personality 'type' in the results. 
var answerData = [ 
    {name: "Ninja" , score: 0}, 
    {name: "Robot" , score: 0}, 
    {name: "Pirate" , score: 0}, 
    {name: "Zombie" , score: 0} ] 

// Get all of the .buttons elements 
var buttons = document.querySelectorAll(".button"); 
// Add an onclick event listener to every element with a class of .buttons 
for (var i = 0 ; i < buttons.length ; i++) { 
    // When an element with .buttons is clicked, run the function called buttonClicked 
    buttons[i].onclick = buttonClicked; 
    } 

// Define what buttonClicked does 
function buttonClicked() { 
    // Get the current element's data-score value 
    var selectedType = this.dataset.score; 
    // Increase the selected answer's 'type' by 1 
    answerData["selectedType"].score++; 
    // Hide the current question div 
    this.parentElement.style.display = "none"; 
    // Work out what the next question div is 
    var nextQuestion = this.parentElement.dataset.next; 
    // Display the next question element 
    document.getElementById(nextQuestion).style.display = "block"; 
} 

Fiddle mit dem, was ich bisher https://jsfiddle.net/funkefiddle/e1za0gtr/1/

Aus irgendeinem Grunde getan habe habe ich beschlossen, dass die Daten-Score ein guter Ort war, eine Verbindung zwischen dem klickbaren Antwort Elemente zu machen und tatsächlich eine Spur davon zu halten. Natürlich funktioniert mein Code nicht wirklich. Die Firefox-Konsole zeigt "this.dataset.score is undefined".

var selectedType = this.dataset.score.value; 
answerData["selectedType"].score++; 

Bitte halbieren.

Auch - ich habe keine Ahnung, ob der Code zum Anzeigen des nächsten Elements in der Serie noch funktioniert, da meine Fehlerüberprüfung es noch nicht so weit gebracht hat. Ich habe nur geschrieben, was mein Gehirn vorgeschlagen hat, könnte funktionieren.

Edit: Ich habe die .value los, weil ich nicht weiß, warum ich es dort an erster Stelle hatte. Auch die letzte Zeile wurde geändert, um nextQuestion eine Variable anstelle einer Zeichenfolge zu machen. Die Fragen zeigen jetzt/verstecken sich in Progression (wenn ich die answerData Zeile aus kommentieren.

Ich denke, das bedeutet, dass ich auf der Linie bin stecken, dass ich den Array-Wert für die gewählte Antworttyp erhöhen möchten.

answerData[selectedType].score++ ; 

Antwort

1

Mehrere Dinge zu korrigieren:

  1. Wie Sie den Handler an die ol Elemente gebunden, this bezieht sich auf dieses Element. Die Punktzahl Daten sind nicht für dieses Element vorhanden. Stattdessen können Sie das target des Ereignisobjekts verwenden, um das Element zu kennen, auf das tatsächlich geklickt wurde.

  2. Wenn der Wert des Attributs data-score abrufen, sollten Sie nur auf dataset.score beziehen, nicht dataset.score.value

  3. answerData["selectedType"] hat zwei Probleme: es answerData nicht als Array-Adressen, sondern als Objekt; und "selectedType" ist ein Literal, das nicht zum Wert der Variablen mit dem gleichen Namen wird. Entfernen Sie die Anführungszeichen, und Ihre Datenstruktur ändern answerData zu einem einfachen Objekt, anstelle eines Arrays:

    var answerData = { // one object, with names as keys, scores as values 
        "Ninja": 0, 
        "Robot": 0, 
        "Pirate": 0, 
        "Zombie": 0}; 
    
  4. Das Argument getElementById nicht mit einem Hash beginnen soll. Sie müssen die ID als solche, ohne Hash übergeben.

  5. ... und brauchen die anderen Fragen mit dem Ninja Sache zu beenden ... ;-)

Hier ist der Code mit diesen Korrekturen - ich nicht vollständig Punkt 5 vollständig tat:

// Create a listener for clicks on the 'start the quiz' button on the front page. 
 
document.getElementById("beginquiz").addEventListener("click", startQuiz); 
 

 
// When the button is clicked the 'intro' div is hidden and the first question div is displayed 
 
function startQuiz() { 
 
    document.getElementById("intro").style.display = "none"; 
 
    document.getElementById("q1").style.display = "block"; 
 
} 
 

 
// Create an array object to store all the quiz answers. Each selected answer should increase the category score by 1. The highest score will be the personality 'type' in the results. 
 
var answerData = { // one object, with names as keys, scores as values 
 
    "Ninja": 0, 
 
    "Robot": 0, 
 
    "Pirate": 0, 
 
    "Zombie": 0}; 
 

 
// Get all of the .buttons elements 
 
var buttons = document.querySelectorAll(".button"); 
 
// Add an onclick event listener to every element with a class of .buttons 
 
for (var i = 0 ; i < buttons.length ; i++) { 
 
    // When an element with .buttons is clicked, run the function called buttonClicked 
 
    buttons[i].onclick = buttonClicked; 
 
    } 
 

 
// Define what buttonClicked does 
 
function buttonClicked(e) { 
 
    var target = e.target; // 1. `this` is parent, need target 
 
    console.log(target); 
 
    // Get the current element's data-score value 
 
    var selectedType = target.dataset.score; // 2. score is the value 
 
    // Increase the selected answer's 'type' by 1 
 
    console.log(selectedType); 
 
    answerData[selectedType]++; // 4. after change of structure 
 
    // Hide the current question div 
 
    this.parentElement.style.display = "none"; 
 
    // Work out what the next question div is 
 
    var nextQuestion = this.parentElement.dataset.next; 
 
    // Display the next question element 
 
    console.log(nextQuestion); 
 
    document.getElementById(nextQuestion).style.display = "block"; // no hash! 
 
}
.question, #result { 
 
    display: none; 
 
    } 
 

 
.button li { 
 
    border: 1px solid; 
 
    border-radius: 3px; 
 
    background-color: #eee; 
 
    text-align: center; 
 
    line-height: 2em; 
 
    padding: 0.5em; 
 
    margin: 0.5em; 
 
    width: 80%; 
 
    margin: 0 auto; 
 
} 
 

 
.button li:hover { 
 
    color: #bfbfbf; 
 
    background-color: #555; 
 
} 
 

 
#intro, .question, #result { 
 
    max-width: 600px; 
 
    margin: 0 auto; 
 
} 
 

 
#beginquiz { 
 
    border: 1px solid; 
 
    border-radius: 3px; 
 
    background-color: #eee; 
 
    text-align: center; 
 
    line-height: 2em; 
 
    padding: 0.5em; 
 
    margin: 0.5em; 
 
    width: 20em; 
 
    margin: 0 auto; 
 
} 
 
#beginquiz:hover { 
 
    color: #bfbfbf; 
 
    background-color: #555; 
 
}
<div id="intro"> 
 
    <h2>Welcome to Ewan L's Assignment 1 Quiz.</h2> 
 
    <button id="beginquiz">Start the quiz</button> 
 
</div> 
 

 
<div class="question" id="q1" data-next="q2"> 
 
    <h2>Question 1:</h2> 
 
    <p>Which of the following is your favourite movie? </p> 
 
    <ol class="button"> 
 
    <li data-score="Ninja">Karate Kid</li> 
 
    <li data-score="Robot">Wall-E</li> 
 
    <li data-score="Pirate">Pirates of the Caribbean</li> 
 
    <li data-score="Zombie">Dawn of the Dead</li> 
 
    </ol> 
 
</div> 
 

 
<div class="question" id="q2" data-next="q3"> 
 
    <h2>Question 2:</h2> 
 
    <p>A building is on fire and you hear a child's screaming for help from the third floor window. Do you: </p> 
 
    <ol class="button"> 
 
    <li data-score="Ninja">Mysteriously disappear and re-appear with the children</li> 
 
    <li data-score="Robot">Run in and save the child on the second floor, because i'm made of metal and fire won't hurt me!</li> 
 
    <li data-score="Pirate">Dress up as a pirate and loot the surrounding neighbourhood, including the bank?</li> 
 
    <li data-score="Zombie">Eat all the brains. Nom nom uuuuggghhh.</li> 
 
    </ol> 
 
</div> 
 

 
<div class="question" id="q3" data-next="q4"> 
 
    <h2>Question 3:</h2> 
 
    <p>Where do you call home?</p> 
 
    <ol class="button"> 
 
    <li data-score="Ninja">A magical castle in the English countryside </li> 
 
    <li data-score="Robot">A dark and secret cave in the distant mountains</li> 
 
    <li>A secluded hut in the woods</li> 
 
    <li>34 Tooranimble St, Kanimboolaga NSW</li> 
 
    <li>The sea is my only home. Man the rigging you scurvy sea dog! YARR</li> 
 
    </ol> 
 
</div> 
 

 
<div class="question" id="q4" data-next="q5"> 
 
    <h2>Question 4:</h2> 
 
    <p>What is your favourite letter?</p> 
 
    <ol class="button"> 
 
    <li data-score="Ninja">A</li> 
 
    <li data-score="Robot">B</li> 
 
    <li>C</li> 
 
    <li>Rrrr</li> 
 
    </ol> 
 
</div> 
 
<div class="question" id="q5" data-next="q6"> 
 
    <h2>Question 5:</h2> 
 
    <p>What is your favourite music?</p> 
 
    <ol class="button"> 
 
    <li data-score="Ninja">Rrrr and B</li> 
 
    <li data-score="Robot">Robo-boogie</li> 
 
    <li></li> 
 
    <li></li> 
 
    </ol> 
 
</div> 
 
<div class="question" id="q6" data-next="q7"> 
 
    <h2>Question 6:</h2> 
 
    <p>If you were a pirate, would you:</p> 
 
    <ol class="button"> 
 
    <li data-score="Ninja">Lead a quiet life of solace and penance</li> 
 
    <li data-score="Robot">Loot and plunder</li> 
 
    <li>Wear an eye-patch</li> 
 
    <li>Have one leg</li> 
 
    <li>All of the above, except for number 1. </li> 
 
    </ol> 
 
</div> 
 
<div class="question" id="q7" data-next="result"> 
 
    <h2>Question 7:</h2> 
 
    <p>Do you like pirates?</p> 
 
    <ol class="button"> 
 
    <li data-score="Ninja">Yes</li> 
 
    <li data-score="Robot">No</li> 
 
    <li>I'm just here for the free cookies</li> 
 
    <li>How did i get this far into the quiz? What am i doing with my life??</li> 
 
    </ol> 
 
</div> 
 

 
<div id="result"> 
 
    <h2>HAHA we fooled you matey. You're a pirate through and through.</h2> 
 
</div>

+0

Ich scherze Sie nicht, wie ich diese Antwort meine Spotify-Playlist begann zu spielen "Komm und hol deine Liebe" von den Guardians of the Galaxy genial Mix vol.1 Vielen Dank für die Antwort. Ich hatte vorher noch nie von Event-Zielen gehört. – Funkexchange

+0

Gern geschehen. Lass mich wissen, welchen nächsten Song du hören möchtest: P – trincot

1

answerData ist ein Array, aber Sie verwenden es, als ob es ein Objekt mit Eigenschaften ist Sie können entweder das Array in ein Objekt mit den Eigenschaftsnamen ändern oder Sie müssen die name -Eigenschaft zuordnen und den Index der ausgewählter Wert.

Entweder das Array wie so zu einem Objekt ändern:

var answerData = { 
    "Ninja": { score: 0 }, 
    "Robot": { score: 0 }, 
    "Pirate": { score: 0 }, 
    "Zombie": { score: 0 } 
} 

Und einen schnellen Wechsel von 'selectedType' string dem eigentlichen Objekt:

answerData[selectedType].score++; // remove quote around selectedType 

Oder es als Array halten, aber Update die Art, wie Sie es aktualisieren, indem Sie zuerst ein Array erstellen, das die Namen abbildet:

Ihr Code wird t Henne sehen wie folgt aus:

// Get the current element's data-score value 
var selectedType = this.dataset.score; 
// Increase the selected answer's 'type' by 1 
var selectedIndex = answerDataNames.indexOf(selectedType); 
answerData[selectedIndex].score++; 
+0

Objekt mit Eigenschaften ist auf jeden Fall, was ich im Sinn hatte. Ich aktualisierte die JS zu: Funktion buttonClicked() { \t var selectedType = this.dataset.score; \t answerData [selectedType] .score ++; \t this.parentElement.style.display = "none"; \t var nextQuestion = this.parentElement.dataset.next; \t document.getElementById (nextQuestion) .style.display = "block"; } Allerdings bekomme ich immer noch einen Konsolenfehler "TypeError: answerData [selectedType] ist undefined" – Funkexchange

+1

@Funkyflow selectedType ist wahrscheinlich undefiniert. Diese Lösung wird durch trincot beantwortet.Also alles, was Sie tun müssen, ist, diesen Code-Schnipsel aus seinem Teil mit mir zu kombinieren – Hoyen