Как я могу создать al oop, который будет задавать вопросы, хранящиеся в массиве объектов, а также создавать кнопки с написанными на них ответами? - PullRequest
0 голосов
/ 06 августа 2020

Я пытаюсь создать игру-викторину, в которой задаю несколько простых вопросов о Гарри Поттере. В викторине есть начальный экран, на котором объясняются правила.

При нажатии кнопки запуска тест начинается вместе с 75-секундным таймером. При неправильном выборе ответа 10 секунд вычитаются из общего времени. Я создал файл basi c HTML и js для викторины, но не могу заставить вопросы циклически повторяться вместе с ответами на кнопках.

var startScreen = document.querySelector(".startScreen");
var startButton = document.querySelector("#startButton");
var quizScreen = document.querySelector(".quizScreen");
var questionText = document.querySelector("#questionText");
var container = document.querySelector(".container");
var hpTitle = document.querySelector("#hpTitle");
var buttons = document.querySelector("#buttons");
var timerEl = document.querySelector("#count");

var answerArrofObjIndex = 0;

var answerArrofObj = [{
    question: "What is the name of Harry Potters owl?",
    answerArr: ["Hedwig", "Trevour", "Crookshanks", "Dobby"],
    correctIndex: 0
  },
  {
    question: "What is Ron's last name?",
    answerArr: ["Swanson", "Weasley", "Granger", "Potter"],
    correctIndex: 1
  },
  {
    question: "Who is the main villain in Harry Potter",
    answerArr: ["Dumbledoor", "Trevour", "Voldemort", "Seious Black"],
    correctIndex: 2
  },
  {
    question: "Who is Harry Potters godfather?",
    answerArr: ["Tom Riddle", "Severus Snape", "Lucious Malfoy", "Serious Black"],
    correctIndex: 3
  }
]


//start button

startButton.addEventListener("click", setCounter)

function setCounter() {
  if (event.target.matches("button")) {
    startScreen.setAttribute("style", "display: none !important");
    quizScreen.setAttribute("style", "display: block !important");
  }
  var timeLeft = 75;

  var timeInterval = setInterval(function() {
    timerEl.textContent = "time left: " + timeLeft;
    timeLeft--;

    if (timeLeft === 0) {
      timerEl.textContent = "time left: 0";
      clearInterval(timeInterval);
      endScreen();
    }

  }, 1000);

  displayQuestions();
}


function displayQuestions() {

  if (answerArrofObjIndex !== 0) {
    document.getElementById("questionText").children[1].remove();

  }

  var currentLayout = answerArrofObj[answerArrofObjIndex];

  var question = document.createElement("h3");
  question.classList.add("text-center");
  question.setAttribute("src", currentLayout.answerArr[currentLayout.correctIndex])

  document.getElementById("questionText").appendChild(question);

  for (var i = 0; i < currentLayout.questionArr.length; i++) {
    setQuestion(i)
  }

}

setCounter();
<head>

  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">


  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/css/bootstrap.min.css" integrity="sha384-VCmXjywReHh4PwowAiWNagnWcLhlEJLA5buUprzK8rxFgeH0kww/aWY76TfkUoSX" crossorigin="anonymous">

  <title>Harry Potter Quiz</title>
</head>

<body class="text-monospace">

  <header>
    <a href="high-scores.html" class="text-left btn btn-outline-success mt-0 ml-3 float-left" type="button">view
                high
                scores</a>
    <p class="h4 text-right mr-4 mt-2"><span id="count">time left: 75</span></p>
  </header>

  <main class="container text-center">
    <article class="startScreen">

      <h1 class="text-center m-5" id="hpTitle">Harry Potter Quiz!</h1>
      <p class="text-center" id="instructions"> Welcome to the Harry Potter quiz, if you would like to test your knowledge on all things wizard and witch please click the start button. You have 75 seconds to complete the quiz, everytime you answer incorectly you are docked 10 seconds, the time
        left after the quiz is your final score.
      </p>

      <button type="button" class="btn btn-secondary mt-4" id="startButton"> start the quiz!</button>
    </article>

    <div class="d-none quizScreen">

      <div id="questionText">
        <h3>question goes here</h3>
      </div>

      <div class="buttons">
        <button id="0" type="button" class="btn btn-secondary btn-block mt-4">answer1</button>
        <button id="1" type="button" class="btn btn-secondary btn-block">answer2</button>
        <button id="2" type="button" class="btn btn-secondary btn-block">answwe3</button>
        <button id="3" type="button" class="btn btn-secondary btn-block">answer4</button>
      </div>

    </div>

    <div class="endScreen d-none">

      <h3 id="endTitle"></h3>
      <p id="finalScore">your final score is:</p>
    </div>
  </main>

  <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/js/bootstrap.min.js" integrity="sha384-XEerZL0cuoUbHE4nZReLT7nx9gQrQreJekYhJD9WNWhH8nEW+0c5qq7aIo2Wl30J" crossorigin="anonymous"></script>
</body>

Высокие баллы:

var startScreen = document.querySelector(".startScreen");
var startButton = document.querySelector("#startButton");
var quizScreen = document.querySelector(".quizScreen");
var questionText = document.querySelector("#questionText");
var container = document.querySelector(".container");
var hpTitle = document.querySelector("#hpTitle");
var buttons = document.querySelector("#buttons");
var timerEl = document.querySelector("#count");

var answerArrofObjIndex = 0;

var answerArrofObj = [{
    question: "What is the name of Harry Potters owl?",
    answerArr: ["Hedwig", "Trevour", "Crookshanks", "Dobby"],
    correctIndex: 0
  },
  {
    question: "What is Ron's last name?",
    answerArr: ["Swanson", "Weasley", "Granger", "Potter"],
    correctIndex: 1
  },
  {
    question: "Who is the main villain in Harry Potter",
    answerArr: ["Dumbledoor", "Trevour", "Voldemort", "Seious Black"],
    correctIndex: 2
  },
  {
    question: "Who is Harry Potters godfather?",
    answerArr: ["Tom Riddle", "Severus Snape", "Lucious Malfoy", "Serious Black"],
    correctIndex: 3
  }
]


//start button

startButton.addEventListener("click", setCounter)

function setCounter() {
  if (event.target.matches("button")) {
    startScreen.setAttribute("style", "display: none !important");
    quizScreen.setAttribute("style", "display: block !important");
  }
  var timeLeft = 75;

  var timeInterval = setInterval(function() {
    timerEl.textContent = "time left: " + timeLeft;
    timeLeft--;

    if (timeLeft === 0) {
      timerEl.textContent = "time left: 0";
      clearInterval(timeInterval);
      endScreen();
    }

  }, 1000);

  displayQuestions();
}


function displayQuestions() {

  if (answerArrofObjIndex !== 0) {
    document.getElementById("questionText").children[1].remove();

  }

  var currentLayout = answerArrofObj[answerArrofObjIndex];

  var question = document.createElement("h3");
  question.classList.add("text-center");
  question.setAttribute("src", currentLayout.answerArr[currentLayout.correctIndex])

  document.getElementById("questionText").appendChild(question);

  for (var i = 0; i < currentLayout.questionArr.length; i++) {
    setQuestion(i)
  }

}

setCounter();
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/css/bootstrap.min.css" integrity="sha384-VCmXjywReHh4PwowAiWNagnWcLhlEJLA5buUprzK8rxFgeH0kww/aWY76TfkUoSX" crossorigin="anonymous">

  <title>High scores!</title>
</head>

<body class="text-monospace">

  <a href="index.html" class="text-left btn btn-outline-success m-3 float-left" type="button">back to quiz</a>
  <div class="container">

    <h1>High Scores!</h1>

  </div>

  <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/js/bootstrap.min.js" integrity="sha384-XEerZL0cuoUbHE4nZReLT7nx9gQrQreJekYhJD9WNWhH8nEW+0c5qq7aIo2Wl30J" crossorigin="anonymous"></script>
</body>

Ответы [ 3 ]

0 голосов
/ 06 августа 2020

L oop через массив вопросов, построить вопрос Затем l oop через массив ответов и построить ответы

Это проще всего сделать с помощью шаблонных литералов

Пример

var answerArrofObj = [{
    question: "What is the name of Harry Potters owl?",
    answerArr: ["Hedwig", "Trevour", "Crookshanks", "Dobby"],
    correctIndex: 0
  },
  {
    question: "What is Ron's last name?",
    answerArr: ["Swanson", "Weasley", "Granger", "Potter"],
    correctIndex: 1
  },
  {
    question: "Who is the main villain in Harry Potter",
    answerArr: ["Dumbledoor", "Trevour", "Voldemort", "Seious Black"],
    correctIndex: 2
  },
  {
    question: "Who is Harry Potters godfather?",
    answerArr: ["Tom Riddle", "Severus Snape", "Lucious Malfoy", "Serious Black"],
    correctIndex: 3
  }
]

let HTML = "";
for (const i in answerArrofObj) {
  HTML += `<h2>${answerArrofObj[i].question}</h2>`;
  for (const j in answerArrofObj[i].answerArr) {
    HTML += `<input type="radio" value="${j}" name="question${i}" id="${i}${j}"></input>`;
    HTML += `<label for="${i}${j}">${answerArrofObj[i].answerArr[j]}</label>`;
  }
}
document.getElementById("holder").innerHTML = HTML;
<div id="holder"></div>
0 голосов
/ 07 августа 2020

Сначала мы определим глобальный контекст, в нем должно быть не менее трех переменных: 'timeLeft', 'answerArrofObjIndex' и 'timeInterval' (должны быть объявлены вне области действия любой функции).

var timeLeft = 75;
var answerArrofObjIndex = 0;
var timeInterval = null;

Теперь нам нужна функция для отображения текущего вопроса на экране.

/*
q: question in the answerArrofObj array
onAnswered: callback called when any of the options is clicked, receives as a parameter a boolean indicating whether the answer is correct
*/
function drawQuestion(q, onAnswered) {
  questionText.querySelector("h3").innerText = q.question;
  q.answerArr.forEach((option, i) => {
    try {
      var old_button = buttons.querySelector(
        "button:nth-child(" + (i + 1) + ")"
      );
      var new_element = old_button.cloneNode(true);
      new_element.innerHTML = option;
      new_element.addEventListener("click", () => onAnswered(q.correctIndex === i));
      old_button.parentNode.replaceChild(new_element, old_button);
    } catch (error) {
      console.error('Error while draw the ' + (i + 1) +  "th button:", error);
    }
  });
}

Также есть ошибка в селекторе div, где находятся кнопки, класс назначен, но селектор ищу идентификатор

var buttons = document.querySelector(".buttons");

с внесенными этими изменениями, отсутствовала только обработка в конце выполнения (функция endScreen)

Версию можно найти здесь:

var startScreen = document.querySelector(".startScreen");
var startButton = document.querySelector("#startButton");
var quizScreen = document.querySelector(".quizScreen");
var questionText = document.querySelector("#questionText");
var container = document.querySelector(".container");
var hpTitle = document.querySelector("#hpTitle");
var buttons = document.querySelector(".buttons");
var timerEl = document.querySelector("#count");

var answerArrofObj = [
  {
    question: "What is the name of Harry Potters owl?",
    answerArr: ["Hedwig", "Trevour", "Crookshanks", "Dobby"],
    correctIndex: 0
  },
  {
    question: "What is Ron's last name?",
    answerArr: ["Swanson", "Weasley", "Granger", "Potter"],
    correctIndex: 1
  },
  {
    question: "Who is the main villain in Harry Potter",
    answerArr: ["Dumbledoor", "Trevour", "Voldemort", "Seious Black"],
    correctIndex: 2
  },
  {
    question: "Who is Harry Potters godfather?",
    answerArr: [
      "Tom Riddle",
      "Severus Snape",
      "Lucious Malfoy",
      "Serious Black"
    ],
    correctIndex: 3
  }
];

//start button

startButton.addEventListener("click", setCounter);

var timeLeft = 75;
var answerArrofObjIndex = 0;
var timeInterval = null;

function setCounter() {
  timeLeft = 75;
  if (event.target.matches("button")) {
    startScreen.setAttribute("style", "display: none !important");
    quizScreen.setAttribute("style", "display: block !important");
  }

  var timeInterval = setInterval(function () {
    timeLeft--;
    timerEl.textContent = "time left: " + timeLeft;

    if (timeLeft === 0) {
      clearInterval(timeInterval);
      endScreen();
    }
  }, 1000);

  displayQuestions();
}

function displayQuestions() {
  if (answerArrofObjIndex >= answerArrofObj.length) {
    if (timeInterval) {
      clearInterval(timeInterval);
    }
    endScreen();
    return;
  }
  var currentLayout = answerArrofObj[answerArrofObjIndex];
  drawQuestion(currentLayout, (rightAnswer) => {
    if (!rightAnswer) {
      timeLeft -= 10;
      timerEl.textContent = "time left: " + timeLeft;
    }
    answerArrofObjIndex++;
    displayQuestions();
  });
}

function drawQuestion(q, onAnswered) {
  questionText.querySelector("h3").innerText = q.question;
  q.answerArr.forEach((option, i) => {
    try {
      var old_button = buttons.querySelector(
        "button:nth-child(" + (i + 1) + ")"
      );
      var new_element = old_button.cloneNode(true);
      new_element.innerHTML = option;
      new_element.addEventListener("click", () => {
        onAnswered(q.correctIndex === i);
      });
      old_button.parentNode.replaceChild(new_element, old_button);
    } catch (error) {
      console.error("Error while draw the " + (i + 1) + "th button:", error);
    }
  });
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />

    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/css/bootstrap.min.css"
      integrity="sha384-VCmXjywReHh4PwowAiWNagnWcLhlEJLA5buUprzK8rxFgeH0kww/aWY76TfkUoSX"
      crossorigin="anonymous"
    />

    <title>Harry Potter Quiz</title>
  </head>

  <body class="text-monospace">
    <header>
      <a
        href="high-scores.html"
        class="text-left btn btn-outline-success mt-0 ml-3 float-left"
        type="button"
        >view high scores</a
      >
      <p class="h4 text-right mr-4 mt-2">
        <span id="count">time left: 75</span>
      </p>
    </header>

    <main class="container text-center">
      <article class="startScreen">
        <h1 class="text-center m-5" id="hpTitle">Harry Potter Quiz!</h1>
        <p class="text-center" id="instructions">
          Welcome to the Harry Potter quiz, if you would like to test your
          knowledge on all things wizard and witch please click the start
          button. You have 75 seconds to complete the quiz, everytime you answer
          incorectly you are docked 10 seconds, the time left after the quiz is
          your final score.
        </p>

        <button type="button" class="btn btn-secondary mt-4" id="startButton">
          start the quiz!
        </button>
      </article>

      <div class="d-none quizScreen">
        <div id="questionText"><h3>question goes here</h3></div>

        <div class="buttons">
          <button id="0" type="button" class="btn btn-secondary btn-block mt-4">
            answer1
          </button>
          <button id="1" type="button" class="btn btn-secondary btn-block">
            answer2
          </button>
          <button id="2" type="button" class="btn btn-secondary btn-block">
            answwe3
          </button>
          <button id="3" type="button" class="btn btn-secondary btn-block">
            answer4
          </button>
        </div>
      </div>

      <div class="endScreen d-none">
        <h3 id="endTitle"></h3>
        <p id="finalScore">your final score is:</p>
      </div>
    </main>

    <script
      src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
      integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
      integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/js/bootstrap.min.js"
      integrity="sha384-XEerZL0cuoUbHE4nZReLT7nx9gQrQreJekYhJD9WNWhH8nEW+0c5qq7aIo2Wl30J"
      crossorigin="anonymous"
    ></script>
  </body>
</html>
0 голосов
/ 06 августа 2020

Я чувствую, что ваша проблема в том, как пройти oop через массив объектов.

answerArrofObj.forEach((el) => {
    let quest = el.question //the question
    let ansArr = el.answerArr  //array of answers

    //You can perform your logicS here
})

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...