如何在HTML中同时显示来自JavaScript数组的5个问题?



我正在开发一个页面的测验或测试有很多问题,在我的HTML它只显示一个问题在一个时间从问题数组我已经创建,但我需要显示5个问题在一个时间,当下一个按钮被点击它需要显示下一组5个问题。我该怎么做呢,请帮帮我。

let questions = [{
numb: 1,
question: "What does HTML stand for?",
answer: "Hyper Text Markup Language",
options: [
"Hyper Text Preprocessor",
"Hyper Text Markup Language",
"Hyper Text Multiple Language",
"Hyper Tool Multi Language"
]
},
{
numb: 2,
question: "What does CSS stand for?",
answer: "Cascading Style Sheet",
options: [
"Common Style Sheet",
"Colorful Style Sheet",
"Computer Style Sheet",
"Cascading Style Sheet"
]
},
{
numb: 3,
question: "What does PHP stand for?",
answer: "Hypertext Preprocessor",
options: [
"Hypertext Preprocessor",
"Hypertext Programming",
"Hypertext Preprogramming",
"Hometext Preprocessor"
]
},
{
numb: 4,
question: "What does SQL stand for?",
answer: "Structured Query Language",
options: [
"Stylish Question Language",
"Stylesheet Query Language",
"Statement Question Language",
"Structured Query Language"
]
},
{
numb: 5,
question: "What does XML stand for?",
answer: "eXtensible Markup Language",
options: [
"eXtensible Markup Language",
"eXecutable Multiple Language",
"eXTra Multi-Program Language",
"eXamine Multiple Language"
]
}]
//for questions
//selecting all required elements
const start_btn = document.querySelector(".start_btn button");
const info_box = document.querySelector(".info_box");
const exit_btn = info_box.querySelector(".buttons .quit");
const continue_btn = info_box.querySelector(".buttons .restart");
const quiz_box = document.querySelector(".quiz_box");
const result_box = document.querySelector(".result_box");
const option_list = document.querySelector(".option_list");
const time_line = document.querySelector("header .time_line");
const timeText = document.querySelector(".timer .time_left_txt");
const timeCount = document.querySelector(".timer .timer_sec");
// if startQuiz button clicked
start_btn.onclick = () => {
// info_box.classList.add("activeInfo"); //show info box
info_box.classList.remove("activeInfo"); //hide info box
quiz_box.classList.add("activeQuiz"); //show quiz box
showQuetions(0); //calling showQestions function
queCounter(1); //passing 1 parameter to queCounter
startTimer(120); //calling startTimer function
startTimerLine(0); //calling startTimerLine function
}

let timeValue = 15;
let que_count = 0;
let que_numb = 1;
let userScore = 0;
let counter;
let counterLine;
let widthValue = 0;
const restart_quiz = result_box.querySelector(".buttons .restart");
const quit_quiz = result_box.querySelector(".buttons .quit");
// if restartQuiz button clicked
restart_quiz.onclick = () => {
quiz_box.classList.add("activeQuiz"); //show quiz box
result_box.classList.remove("activeResult"); //hide result box
timeValue = 15;
que_count = 0;
que_numb = 1;
userScore = 0;
widthValue = 0;
showQuetions(que_count); //calling showQestions function
queCounter(que_numb); //passing que_numb value to queCounter
clearInterval(counter); //clear counter
clearInterval(counterLine); //clear counterLine
startTimer(timeValue); //calling startTimer function
startTimerLine(widthValue); //calling startTimerLine function
timeText.textContent = "Time Left"; //change the text of timeText to Time Left
next_btn.classList.remove("show"); //hide the next button
}
// if quitQuiz button clicked
quit_quiz.onclick = () => {
window.location.reload(); //reload the current window
}
const next_btn = document.querySelector("footer .next_btn");
const bottom_ques_counter = document.querySelector("footer .total_que");
// if Next Que button clicked
next_btn.onclick = () => {
if (que_count < questions.length - 1) { //if question count is less than total question length
que_count++; //increment the que_count value
que_numb++; //increment the que_numb value
showQuetions(que_count); //calling showQestions function
queCounter(que_numb); //passing que_numb value to queCounter
clearInterval(counter); //clear counter
clearInterval(counterLine); //clear counterLine
startTimer(timeValue); //calling startTimer function
startTimerLine(widthValue); //calling startTimerLine function
timeText.textContent = "Time Left"; //change the timeText to Time Left
next_btn.classList.remove("show"); //hide the next button
} else {
clearInterval(counter); //clear counter
clearInterval(counterLine); //clear counterLine
showResult(); //calling showResult function
}
}
// getting questions and options from array
function showQuetions(index) {
const que_text = document.querySelector(".que_text");
//creating a new span and div tag for question and option and passing the value using array index
let que_tag = '<span>' + questions[index].numb + ". " + questions[index].question + '</span>';
let option_tag = '<div class="option"><span>' + questions[index].options[0] + '</span></div>' +
'<div class="option"><span>' + questions[index].options[1] + '</span></div>' +
'<div class="option"><span>' + questions[index].options[2] + '</span></div>' +
'<div class="option"><span>' + questions[index].options[3] + '</span></div>';
que_text.innerHTML = que_tag; //adding new span tag inside que_tag
option_list.innerHTML = option_tag; //adding new div tag inside option_tag
const option = option_list.querySelectorAll(".option");
// set onclick attribute to all available options
for (i = 0; i < option.length; i++) {
option[i].setAttribute("onclick", "optionSelected(this)");
}
}
// creating the new div tags which for icons

let tickIconTag = '<div class="icon tick"><i class="fas fa-check"></i></div>';
let crossIconTag = '<div class="icon cross"><i class="fas fa-times"></i></div>';
//if user clicked on option
function optionSelected(answer) {
clearInterval(counter); //clear counter
clearInterval(counterLine); //clear counterLine
let userAns = answer.textContent; //getting user selected option
let correcAns = questions[que_count].answer; //getting correct answer from array
const allOptions = option_list.children.length; //getting all option items
if (userAns == correcAns) { //if user selected option is equal to array's correct answer
userScore += 1; //upgrading score value with 1
answer.classList.add("correct"); //adding green color to correct selected option
answer.insertAdjacentHTML("beforeend", tickIconTag); //adding tick icon to correct selected option
console.log("Correct Answer");
console.log("Your correct answers = " + userScore);
} else {
answer.classList.add("incorrect"); //adding red color to correct selected option
answer.insertAdjacentHTML("beforeend", crossIconTag); //adding cross icon to correct selected option
console.log("Wrong Answer");
for (i = 0; i < allOptions; i++) {
if (option_list.children[i].textContent == correcAns) { //if there is an option which is matched to an array answer 
option_list.children[i].setAttribute("class", "option correct"); //adding green color to matched option
option_list.children[i].insertAdjacentHTML("beforeend", tickIconTag); //adding tick icon to matched option
console.log("Auto selected correct answer.");
}
}
}
for (i = 0; i < allOptions; i++) {
option_list.children[i].classList.add("disabled"); //once user select an option then disabled all options
}
next_btn.classList.add("show"); //show the next button if user selected any option
}
function showResult() {
info_box.classList.remove("activeInfo"); //hide info box
quiz_box.classList.remove("activeQuiz"); //hide quiz box
result_box.classList.add("activeResult"); //show result box
const scoreText = result_box.querySelector(".score_text");
if (userScore > 3) { // if user scored more than 3
//creating a new span tag and passing the user score number and total question number
let scoreTag = '<span>and congrats! 🎉, You got <p>' + userScore + '</p> out of <p>' + questions.length + '</p></span>';
scoreText.innerHTML = scoreTag; //adding new span tag inside score_Text
} else if (userScore > 1) { // if user scored more than 1
let scoreTag = '<span>and nice 😎, You got <p>' + userScore + '</p> out of <p>' + questions.length + '</p></span>';
scoreText.innerHTML = scoreTag;
} else { // if user scored less than 1
let scoreTag = '<span>and sorry 😐, You got only <p>' + userScore + '</p> out of <p>' + questions.length + '</p></span>';
scoreText.innerHTML = scoreTag;
}
}
function startTimer(time) {
counter = setInterval(timer, 1000);
function timer() {
timeCount.textContent = time; //changing the value of timeCount with time value
time--; //decrement the time value
if (time < 9) { //if timer is less than 9
let addZero = timeCount.textContent;
timeCount.textContent = "0" + addZero; //add a 0 before time value
}
if (time < 0) { //if timer is less than 0
clearInterval(counter); //clear counter
timeText.textContent = "Time Off"; //change the time text to time off
const allOptions = option_list.children.length; //getting all option items
let correcAns = questions[que_count].answer; //getting correct answer from array
for (i = 0; i < allOptions; i++) {
if (option_list.children[i].textContent == correcAns) { //if there is an option which is matched to an array answer
option_list.children[i].setAttribute("class", "option correct"); //adding green color to matched option
option_list.children[i].insertAdjacentHTML("beforeend", tickIconTag); //adding tick icon to matched option
console.log("Time Off: Auto selected correct answer.");
}
}
for (i = 0; i < allOptions; i++) {
option_list.children[i].classList.add("disabled"); //once user select an option then disabled all options
}
next_btn.classList.add("show"); //show the next button if user selected any option
}
}
}
function startTimerLine(time) {
counterLine = setInterval(timer, 29);
function timer() {
time += 1; //upgrading time value with 1
time_line.style.width = time + "px"; //increasing width of time_line with px by time value
if (time > 549) { //if time value is greater than 549
clearInterval(counterLine); //clear counterLine
}
}
}
function queCounter(index) {
//creating a new span tag and passing the question number and total question
let totalQueCounTag = '<span><p>' + index + '</p> of <p>' + questions.length + '</p> Questions</span>';
bottom_ques_counter.innerHTML = totalQueCounTag; //adding new span tag inside bottom_ques_counter
}
<!-- questions -->
<div class="start_btn"><button>Start Answering</button></div>
<!-- Info Box -->
<div class="info_box">
<div class="buttons">
<button class="quit">Exit Quiz</button>
<button class="restart">Continue</button>
</div>
</div>
<!-- Quiz Box -->
<div class="quiz_box">
<header>
<div class="title">Questions</div>
<div class="timer">
<div class="time_left_txt">Time Left</div>
<div class="timer_sec">15</div>
</div>
<div class="time_line"></div>
</header>
<section>
<div class="que_text">
</div>
<div class="option_list">
</div>
</section>
<!-- footer of Quiz Box -->
<footer>
<div class="total_que">
<!-- Here I've inserted Question Count Number from JavaScript -->
</div>
<button class="next_btn">Next Que</button>
</footer>
</div>
<!-- Result Box -->
<div class="result_box">
<div class="icon">
<i class="fas fa-crown"></i>
</div>
<div class="complete_text">You've completed the Quiz!</div>
<div class="score_text">
<!-- Here I've inserted Score Result from JavaScript -->
</div>
<div class="buttons">
<button class="restart">Replay Quiz</button>
<button class="quit">Quit Quiz</button>
</div>
</div>

EDIT:这里是一个repl,其中显示了您想要的NextPrevious按钮

在整个结构周围建立了太多的东西。所以编辑你的代码很困难。相反,我只是做了一个动态问题显示设置(n控制显示的问题数量,因为displayQuestion显示与arr参数一起给出的所有问题)

现在进行一步一步的演练
3主要功能:

  1. startBtn的事件监听器代码中的第一行只是简单地改变了startButton中显示的文本,并不是那么重要。在它的正下方是一个重要的变量n,它将在稍后的过滤器中以这样的方式使用nCONTROLS一次显示的问题数量
  2. displayQuestions函数:这个函数接受2个参数;arrquestionBararr是给定的问题数组(记住,事件侦听器提供了一个智能过滤的问题数组)。它遍历每个问题项,生成一个element(将包含问题及其选项),一个function(将是单击listeners对应所有不同的optionsquestion;当一个选项被选中时,停止从所有选项侦听),然后它通过optionsappend的选项迭代到父question,并将专用listener function添加到每个option
  3. displayResults函数:它接受results对象(在它的第一个参数中),并将主要结果打印到给定元素(在它的第二个参数中)

var questionBar=document.getElementById('questions')
var startBtn=document.getElementById('start')
startBtn.addEventListener('click', async function(){
questionBar.innerHTML="" //important to prevent overlap(move this line to the beginning of the displayQuestions to ONLY show 5 questions at a time on the whole document)
startBtn.innerText="Restart Questions"
var n=5 //change this number to change the amount of questions shown
var results={correct:0,totalPossible:0}
for(var i=0;i<questions.length;i+=n){
var result=await displayQuestions(
questions.filter((a,j)=>j>=i&&j<i+n),
questionBar
)
Object.keys(result).forEach(a=>{
if(a=="correct"){results.correct+=result.correct}
else if(a=="totalPossible"){results.totalPossible+=result.totalPossible}
else{results[a]=result[a]}
})
}
displayResults(results,questionBar)
})
async function displayQuestions(arr,questionBar){
var finished=arr.length //a test for if all questions answered
var answered=0; var correct=0
var corrections={}
arr.forEach(a=>{
var question=document.createElement('div')
question.className="question" //for css to change looks

var options=[] //will become an array of elements(that have the question options) in order to remove event listener from them
//the function below handles when a question option is selected and removes listening when an answer is selected(one can only answer once)
function listen(ev){
var answer=ev.path[0].innerText
if(answer==a.answer){
question.className="correct";correct++;answered++
ev.path[0].className="selected"
corrections[a.numb]={
correct:true, userAnswer:answer, correctAnswer:a.answer
}
}
else{
question.className="wrong";answered++
ev.path[0].className="selected"
corrections[a.numb]={
correct:false, userAnswer:answer, correctAnswer:a.answer
}
}
options.forEach(c=>{c.removeEventListener('click',listen)})
}

var title=document.createElement('span')
title.classList.add('title') //for css to change looks
title.innerText=`(${a.numb}) ${a.question}`
question.appendChild(title)

a.options.forEach(b=>{
var option=document.createElement('div')
option.className="option" //for css to change looks
option.innerText=b
option.addEventListener('click',listen)
options.push(option)
question.appendChild(option)
})
questionBar.appendChild(question)
})
var p=new Promise(results=>{
var i=setInterval(()=>{
if(answered==finished){
clearInterval(i) //the timeout INSIDE the interval ensures that I can fix the time that you have to look at the final display of what was right and wrong before the results function is run
//it's just a personal preference because it looks glitchy when the question immediately goes into results
setTimeout(()=>{
corrections.correct=correct
corrections.totalPossible=finished
results(corrections)
},1000)
}
},0)
})
return await p
}
function displayResults(corrections,elem){
//the corrections object has A LOT of data you can use in MANY ways
console.log(corrections)
var correct=corrections.correct
var totalPossible=corrections.totalPossible
elem.innerText=`You got ${correct} of ${totalPossible}`
}
.wrong {
background-color: red;
border-radius: 5px;
margin: 20px;
}
.correct {
background-color: lightgreen;
border-radius: 5px;
margin: 20px;
}
.question{
background-color: lightblue;
border-radius: 5px;
margin: 20px;
}
.title{
font-weight: bold;
font-family: Verdana;
}
.option{
font-family: Courier, sans-serif;
margin: 5px;
}
.selected{
font-family: Courier, sans-serif;
margin: 5px;
background-color: orange;
}
<div class="start_btn">
<button id="start">Start Questions</button>
</div>
<div id="questions"></div>
<script>
//btw all numb values should be unique.. I'm counting on that xD
let questions = [{
numb: 1,
question: "What does HTML stand for?",
answer: "Hyper Text Markup Language",
options: [
"Hyper Text Preprocessor",
"Hyper Text Markup Language",
"Hyper Text Multiple Language",
"Hyper Tool Multi Language"
]
},
{
numb: 2,
question: "What does CSS stand for?",
answer: "Cascading Style Sheet",
options: [
"Common Style Sheet",
"Colorful Style Sheet",
"Computer Style Sheet",
"Cascading Style Sheet"
]
},
{
numb: 3,
question: "What does PHP stand for?",
answer: "Hypertext Preprocessor",
options: [
"Hypertext Preprocessor",
"Hypertext Programming",
"Hypertext Preprogramming",
"Hometext Preprocessor"
]
},
{
numb: 4,
question: "What does SQL stand for?",
answer: "Structured Query Language",
options: [
"Stylish Question Language",
"Stylesheet Query Language",
"Statement Question Language",
"Structured Query Language"
]
},
{
numb: 5,
question: "What does XML stand for?",
answer: "eXtensible Markup Language",
options: [
"eXtensible Markup Language",
"eXecutable Multiple Language",
"eXTra Multi-Program Language",
"eXamine Multiple Language"
]
},
{
numb: 6,
question: "Why did the cow cross the road",
answer: "There was no road, it was grass",
options: [
"idk LOL",
"COWS CAN'T SWIM",
"There was no road, it was grass",
"Bruh pls, NEXT"
]
},
{
numb: 7,
question: "How to select element with 2 classes(CSS)",
answer: "Chain dots like: .a.b",
options: [
"Chain dots like: .a.b",
"It's impossible",
"Sequence dots like: .a .b",
"explore the universe, then come back"
]
},
{
numb: 8,
question: "What is 9+10?",
answer: "Nineteen",
options: [
"Twenty one",
"nothing at all, irrelevant",
"IDK, YOU TELL ME",
"Nineteen"
]
},
{
numb: 9,
question: "How does a C linked list work?",
answer: "structs and pointer logic",
options: [
"high level javascript magic",
"some random module",
"that doesn't exist",
"structs and pointer logic"
]
},
{
numb: 10,
question: "Is light a particle?",
answer: "It behaves like a particle AND a wave",
options: [
"Affirmitave",
"Nope, not even close",
"It behaves like a particle AND a wave",
"It's a unicorn"
]
},
{
numb: 11,
question: "What is a bit?",
answer: "A binary digit",
options: [
"A binary digit",
"BEEP BOOP",
"69",
"idk smh xD"
]
}
]
</script>

最新更新