Javascript个性测验使用'这个'和data- *属性

时间:2016-04-07 03:38:30

标签: javascript html

我正在尝试使用纯javascript为单一分配创建点击人格测验。我有一堆div,以便它们出现。每个问题都有一个与不同人格类型相关的4个(左右)答案的列表。我打算保留一系列对象来计算每个选定的答案,并在最后提供人格类型的细分。

我目前坚持使用该功能;

  1. 记录所选数据并将其添加到答案数组
  2. 隐藏当前问题div和
  3. 显示下一个问题div
  4. 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";
    }
    

    摆弄到目前为止我所做的事情https://jsfiddle.net/funkefiddle/e1za0gtr/1/

    出于某种原因,我认为数据得分是在可点击的答案元素之间建立联系并实际跟踪它的好地方。但是,显然我的代码实际上并没有工作。 Firefox控制台显示&#34; this.dataset.score未定义&#34;。

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

    请停下来。

    另外 - 我不知道显示系列中下一个元素的代码是否会起作用,因为我的错误检查还没有达到目前为止。我刚刚写了我的大脑建议可能有用的东西。

    编辑:摆脱了.value,因为我不知道为什么我在那里拥有它。 还更改了最后一行,使nextQuestion成为变量而不是字符串。现在问题显示/隐藏在进展中(当我注释掉answerData行时。

    我想这意味着我已经停留在我希望增加所选答案类型的数组值的行上。

    answerData[selectedType].score++ ;
    

2 个答案:

答案 0 :(得分:1)

answerData是一个数组。但是您正在使用它,就像它是具有属性的Object一样。您可以使用属性名称将数组更改为对象,也可以映射name属性并获取所选值的索引。

将数组更改为如下对象:

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

快速更改&#39; selectedType&#39;字符串到实际对象:

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

或者将其保留为数组但通过首先创建一个映射名称的数组来更新更新方式:

var answerDataNames = answerData.map(function(obj){
    return obj.name;
}

您的代码将如下所示:

 // 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++;

答案 1 :(得分:1)

要纠正的几件事:

  1. 当您将处理程序绑定到ol元素时,this引用该元素。该元素上不存在得分数据。相反,您可以使用事件对象的target来了解实际点击的元素。

  2. 检索data-score属性的值时,您应该只引用dataset.score,而不是dataset.score.value

  3. answerData["selectedType"]有两个问题:它不将answerData作为数组,而是作为对象; “selectedType”是一个文字,它不会成为具有相同名称的变量的值。删除引号,并将数据结构answerData更改为普通对象,而不是数组:

    var answerData = { // one object, with names as keys, scores as values
        "Ninja": 0,
         "Robot": 0,
        "Pirate": 0,
        "Zombie": 0};
    
  4. getElementById的参数不应以哈希开头。您需要传递 id ,不需要哈希。

  5. ...你需要用Ninja的东西来完成其他问题... ;-)

  6. 以下是具有这些更正的代码 - 我没有完全完成第5点:

    // 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>