Logo Zephyrnet

Come creare un semplice quiz JavaScript

Data:

"Come posso fare un quiz JavaScript?" è una delle domande più comuni poste dalle persone che imparano lo sviluppo web e per buoni motivi. I quiz sono divertenti! Sono un ottimo modo per conoscere nuovi argomenti e ti consentono di coinvolgere il tuo pubblico con qualcosa di divertente e giocoso.

Questo popolare articolo è stato aggiornato nel 2020 per riflettere le attuali migliori pratiche in JavaScript. Per una conoscenza più approfondita di JavaScript, leggi il nostro libro, JavaScript: Novice to Ninja, 2a edizione.

Come fare un quiz JavaScript

La codifica del tuo quiz JavaScript è anche un fantastico esercizio di apprendimento. Ti insegna come gestire gli eventi, manipolare il DOM, gestire l'input dell'utente, fornire feedback all'utente e tenere traccia del loro punteggio (ad esempio, utilizzando l'archiviazione sul lato client). E quando hai un quiz di base attivo e funzionante, ci sono un sacco di possibilità per aggiungere funzionalità più avanzate, come l'impaginazione. Ci vado a la fine dell'articolo.

In questo tutorial, ti guiderò attraverso la creazione di un quiz JavaScript in più passaggi che potrai adattare alle tue esigenze e aggiungere al tuo sito. Se desideri vedere con cosa finiremo, puoi saltare avanti e vedere il quiz di lavoro.

Cose da tenere presente prima di iniziare

Alcune cose da sapere prima di iniziare:

  • Questo è un tutorial front-end, nel senso che chiunque sappia guardare attraverso il codice sorgente di una pagina può trovare le risposte. Per quiz seri, i dati devono essere gestiti attraverso il back-end, che va oltre lo scopo di questo tutorial.
  • Il codice in questo articolo utilizza la moderna sintassi JavaScript (ES6 +), il che significa che non sarà compatibile con nessuna versione di Internet Explorer. Tuttavia, funzionerà perfettamente sui browser moderni, incluso Microsoft Edge.
  • Se hai bisogno di supportare browser più vecchi, ho scritto a Tutorial per quiz JavaScript compatibile con IE8. Oppure, se desideri un aggiornamento su ES6, dai un'occhiata a questo corso di Darin Haener su SitePoint Premium.
  • Avrai bisogno di familiarità con HTML, CSS e JavaScript, ma ogni riga di codice verrà spiegata individualmente.

La struttura di base del tuo quiz JavaScript

Idealmente, vogliamo che le domande e le risposte del quiz siano nel nostro codice JavaScript e che il nostro script generi automaticamente il quiz. In questo modo, non dovremo scrivere molti markup ripetitivi e possiamo aggiungere e rimuovere facilmente le domande.

Per impostare la struttura del nostro quiz JavaScript, dovremo iniziare con il seguente HTML:

  • A <div> per sostenere il quiz
  • A <button> per inviare il quiz
  • A <div> per visualizzare i risultati

Ecco come sarebbe:

<div id="quiz"></div>
<button id="submit">Submit Quiz</button>
<div id="results"></div>

Possiamo quindi selezionare questi elementi HTML e memorizzare i riferimenti ad essi in variabili in questo modo:

const quizContainer = document.getElementById('quiz');
const resultsContainer = document.getElementById('results');
const submitButton = document.getElementById('submit');

Successivamente avremo bisogno di un modo per creare un quiz, mostrare i risultati e mettere tutto insieme. Possiamo iniziare definendo le nostre funzioni e le riempiremo mentre procediamo:

function buildQuiz(){} function showResults(){} // display quiz right away
buildQuiz(); // on submit, show results
submitButton.addEventListener('click', showResults);

Qui, abbiamo funzioni per costruire il quiz e mostrare i risultati. Gestiremo il nostro buildQuiz funzioni immediatamente e avremo il nostro showResults funzione eseguita quando l'utente fa clic sul pulsante di invio.

Visualizzazione delle domande del quiz

La prossima cosa di cui il nostro quiz ha bisogno sono alcune domande da mostrare. Useremo letterali di oggetti per rappresentare le singole domande e un array per contenere tutte le domande che compongono il nostro quiz. L'uso di un array semplifica l'iterazione delle domande:

const myQuestions = [ { question: "Who invented JavaScript?", answers: { a: "Douglas Crockford", b: "Sheryl Sandberg", c: "Brendan Eich" }, correctAnswer: "c" }, { question: "Which one of these is a JavaScript package manager?", answers: { a: "Node.js", b: "TypeScript", c: "npm" }, correctAnswer: "c" }, { question: "Which tool can you use to ensure code quality?", answers: { a: "Angular", b: "jQuery", c: "RequireJS", d: "ESLint" }, correctAnswer: "d" }
];

Sentiti libero di porre tutte le domande o risposte che desideri.

Nota: poiché si tratta di un array, le domande appariranno nell'ordine in cui sono elencate. Se desideri ordinare le domande in qualsiasi modo prima di presentarle all'utente, dai un'occhiata al nostro rapido suggerimento ordinamento di una matrice di oggetti in JavaScript.

Ora che abbiamo il nostro elenco di domande, possiamo mostrarle sulla pagina. Esamineremo il seguente JavaScript riga per riga per vedere come funziona:

function buildQuiz(){ // variable to store the HTML output const output = []; // for each question... myQuestions.forEach( (currentQuestion, questionNumber) => { // variable to store the list of possible answers const answers = []; // and for each available answer... for(letter in currentQuestion.answers){ // ...add an HTML radio button answers.push( `<label> <input type="radio" name="question${questionNumber}" value="${letter}"> ${letter} : ${currentQuestion.answers[letter]} </label>` ); } // add this question and its answers to the output output.push( `<div class="question"> ${currentQuestion.question} </div> <div class="answers"> ${answers.join('')} </div>` ); } ); // finally combine our output list into one string of HTML and put it on the page quizContainer.innerHTML = output.join('');
}

Innanzitutto, creiamo un output variabile per contenere tutto l'output HTML, comprese le domande e le opzioni di risposta.

Successivamente, possiamo iniziare a creare l'HTML per ogni domanda. Dovremo passare in rassegna ogni domanda in questo modo:

myQuestions.forEach( (currentQuestion, questionNumber) => { // the code we want to run for each question goes here
});

Per brevità, stiamo usando un funzione freccia per eseguire le nostre operazioni su ogni domanda. Perché questo è in a forEach loop, otteniamo il valore corrente, l'indice (il numero di posizione dell'elemento corrente nell'array) e l'array stesso come parametri. Abbiamo solo bisogno del valore attuale e dell'indice, che per i nostri scopi, chiameremo currentQuestion ed questionNumber rispettivamente.

Ora diamo un'occhiata al codice all'interno del nostro ciclo:

// we'll want to store the list of answer choices
const answers = []; // and for each available answer...
for(letter in currentQuestion.answers){ // ...add an html radio button answers.push( `<label> <input type="radio" name="question${questionNumber}" value="${letter}"> ${letter} : ${currentQuestion.answers[letter]} </label>` );
} // add this question and its answers to the output
output.push( `<div class="question"> ${currentQuestion.question} </div> <div class="answers"> ${answers.join('')} </div>`
);

Per ogni domanda, vorremmo generare l'HTML corretto, quindi il nostro primo passo è creare un array per contenere l'elenco delle possibili risposte.

Successivamente, utilizzeremo un ciclo per compilare le possibili risposte per la domanda corrente. Per ogni scelta, stiamo creando un pulsante di opzione HTML, che racchiudiamo in a <label> elemento. Ciò consente agli utenti di fare clic in qualsiasi punto del testo della risposta per selezionare quella risposta. Se l'etichetta fosse omessa, gli utenti dovrebbero fare clic sul pulsante di opzione stesso, che non è molto accessibile.

Si noti che stiamo usando letterali modello, che sono stringhe ma più potenti. Faremo uso delle seguenti funzionalità:

  • capacità multilinea
  • non è più necessario fuga virgolette tra virgolette perché i letterali dei template usano invece i backtick
  • interpolazione di stringhe, in modo da poter incorporare espressioni JavaScript direttamente nelle stringhe in questo modo: ${code_goes_here}.

Una volta che abbiamo il nostro elenco di pulsanti di risposta, possiamo inserire la domanda HTML e la risposta HTML nel nostro elenco complessivo di output.

Si noti che stiamo usando un modello letterale e alcune espressioni incorporate per creare prima il div della domanda e quindi creare il div della risposta. Il join espressione prende il nostro elenco di risposte e le riunisce in una stringa che possiamo generare nel nostro answers div

Ora che abbiamo generato l'HTML per ogni domanda, possiamo unirci tutti insieme e mostrarlo sulla pagina:

quizContainer.innerHTML = output.join('');

Ora nostro buildQuiz la funzione è completa.

A questo punto dovresti essere in grado di eseguire il quiz e visualizzare le domande visualizzate. Si noti, tuttavia, che la struttura del codice è importante. A causa di qualcosa chiamato il zona morta temporale, non è possibile fare riferimento alla matrice di domande prima che sia stata definita.

Per ricapitolare, questa è la struttura corretta:

// Functions
function buildQuiz(){ ... }
function showResults(){ ... } // Variables
const quizContainer = document.getElementById('quiz');
const resultsContainer = document.getElementById('results');
const submitButton = document.getElementById('submit');
const myQuestions = [ ... ]; // Kick things off
buildQuiz(); // Event listeners
submitButton.addEventListener('click', showResults);

Visualizzazione dei risultati del quiz

A questo punto, vogliamo costruire il nostro showResults funzione per scorrere le risposte, controllarle e mostrare i risultati.

Ecco la funzione, che vedremo in dettaglio in seguito:

function showResults(){ // gather answer containers from our quiz const answerContainers = quizContainer.querySelectorAll('.answers'); // keep track of user's answers let numCorrect = 0; // for each question... myQuestions.forEach( (currentQuestion, questionNumber) => { // find selected answer const answerContainer = answerContainers[questionNumber]; const selector = `input[name=question${questionNumber}]:checked`; const userAnswer = (answerContainer.querySelector(selector) || {}).value; // if answer is correct if(userAnswer === currentQuestion.correctAnswer){ // add to the number of correct answers numCorrect++; // color the answers green answerContainers[questionNumber].style.color = 'lightgreen'; } // if answer is wrong or blank else{ // color the answers red answerContainers[questionNumber].style.color = 'red'; } }); // show number of correct answers out of total resultsContainer.innerHTML = `${numCorrect} out of ${myQuestions.length}`;
}

Innanzitutto, selezioniamo tutti i contenitori di risposte nell'HTML del nostro quiz. Quindi creeremo variabili per tenere traccia della risposta corrente dell'utente e del numero totale di risposte corrette.

// gather answer containers from our quiz
const answerContainers = quizContainer.querySelectorAll('.answers'); // keep track of user's answers
let numCorrect = 0;

Ora possiamo scorrere ogni domanda e controllare le risposte.

// for each question...
myQuestions.forEach( (currentQuestion, questionNumber) => { // find selected answer const answerContainer = answerContainers[questionNumber]; const selector = `input[name=question${questionNumber}]:checked`; const userAnswer = (answerContainer.querySelector(selector) || {}).value; // if answer is correct if(userAnswer === currentQuestion.correctAnswer){ // add to the number of correct answers numCorrect++; // color the answers green answerContainers[questionNumber].style.color = 'lightgreen'; } // if answer is wrong or blank else{ // color the answers red answerContainers[questionNumber].style.color = 'red'; }
});

L'essenza generale di questo codice è:

  • trova la risposta selezionata nell'HTML
  • gestire cosa succede se la risposta è corretta
  • gestire cosa succede se la risposta è errata.

Diamo un'occhiata più da vicino a come troviamo la risposta selezionata nel nostro HTML:

// find selected answer
const answerContainer = answerContainers[questionNumber];
const selector = `input[name=question${questionNumber}]:checked`;
const userAnswer = (answerContainer.querySelector(selector) || {}).value;

Innanzitutto, ci assicuriamo che stiamo cercando nel contenitore delle risposte la domanda corrente.

Nella riga successiva, stiamo definendo un selettore CSS che ci permetterà di trovare quale pulsante di opzione è selezionato.

Quindi stiamo usando JavaScript querySelector per cercare il nostro selettore CSS nel precedentemente definito answerContainer. In sostanza, questo significa che troveremo quale pulsante di opzione della risposta è selezionato.

Infine, possiamo ottenere il valore di quella risposta utilizzando .value.

Gestione di input utente incompleti

E se l'utente ha lasciato vuota una risposta? In questo caso, usando .value causerebbe un errore perché non puoi ottenere il valore di qualcosa che non c'è. Per risolvere questo, abbiamo aggiunto ||, che significa "o", e {}, che è un oggetto vuoto. Ora la dichiarazione generale dice:

  • Ottieni un riferimento al nostro elemento di risposta selezionato OPPURE, se non esiste, usa un oggetto vuoto.
  • Ottieni il valore di qualunque cosa fosse nella prima affermazione.

Di conseguenza, il valore sarà la risposta dell'utente o undefined, il che significa che un utente può saltare una domanda senza interrompere il nostro quiz.

Valutazione delle risposte e visualizzazione del risultato

Le prossime dichiarazioni nel nostro ciclo di verifica delle risposte ci permetteranno di gestire le risposte corrette e errate.

// if answer is correct
if(userAnswer === currentQuestion.correctAnswer){ // add to the number of correct answers numCorrect++; // color the answers green answerContainers[questionNumber].style.color = 'lightgreen';
}
// if answer is wrong or blank
else{ // color the answers red answerContainers[questionNumber].style.color = 'red';
}

Se la risposta dell'utente corrisponde alla scelta corretta, aumenta il numero di risposte corrette di una e (facoltativamente) colora di verde l'insieme di scelte. Se la risposta è errata o vuota, colorare le opzioni di risposta in rosso (di nuovo, facoltativo).

Una volta terminato il ciclo di verifica delle risposte, possiamo mostrare quante domande l'utente ha fatto bene:

// show number of correct answers out of total
resultsContainer.innerHTML = `${numCorrect} out of ${myQuestions.length}`;

E ora abbiamo un quiz JavaScript funzionante!

Se lo desideri, puoi racchiudere l'intero quiz in un IIFE (espressione di funzione immediatamente richiamata), che è una funzione che viene eseguita non appena definita. Ciò manterrà le tue variabili al di fuori dell'ambito globale e assicurerà che il tuo quiz non interferisca con altri script in esecuzione sulla pagina.

(function(){ // put the rest of your code here
})();

Ora sei pronto! Sentiti libero di aggiungere o rimuovere domande e risposte e modellare il quiz come preferisci.

A questo punto, il tuo quiz potrebbe assomigliare a questo (con un po 'di stile):

Vedi la penna
Quiz JavaScript semplice (nessuna impaginazione)
di SitePoint (@SitePoint)
on CodePen.

Ora abbiamo in esecuzione il nostro quiz di base, diamo un'occhiata ad alcune funzionalità più avanzate. Ad esempio, supponiamo che tu voglia mostrare solo una domanda alla volta.

Avrete bisogno di:

  • un modo per mostrare e nascondere domande
  • pulsanti per navigare nel quiz.

Dovremo fare alcuni aggiornamenti, quindi iniziamo con l'HTML:

<div class="quiz-container"> <div id="quiz"></div>
</div>
<button id="previous">Previous Question</button>
<button id="next">Next Question</button>
<button id="submit">Submit Quiz</button>
<div id="results"></div>

La maggior parte di quel markup è la stessa di prima, ma ora abbiamo aggiunto pulsanti di navigazione e un contenitore di quiz. Il contenitore dei quiz ci aiuterà a posizionare le domande come livelli che possiamo mostrare e nascondere.

Successivamente, all'interno del buildQuiz funzione, dobbiamo aggiungere un <div> elemento con classe slide per contenere la domanda e rispondere ai contenitori che abbiamo appena creato:

output.push( `<div class="slide"> <div class="question"> ${currentQuestion.question} </div> <div class="answers"> ${answers.join("")} </div> </div>`
);

Successivamente, possiamo utilizzare alcuni posizionamenti CSS per far sì che le diapositive si posizionino come livelli uno sopra l'altro. In questo esempio, noterai che stiamo usando gli z-index e le transizioni di opacità per consentire alle nostre diapositive di sfumare dentro e fuori. Ecco come potrebbe apparire quel CSS:

.slide{ position: absolute; left: 0px; top: 0px; width: 100%; z-index: 1; opacity: 0; transition: opacity 0.5s;
}
.active-slide{ opacity: 1; z-index: 2;
}
.quiz-container{ position: relative; height: 200px; margin-top: 40px;
}

Ora aggiungeremo un po 'di JavaScript per far funzionare l'impaginazione. Come prima, l'ordine è importante, quindi questa è la struttura rivista del nostro codice:

// Functions
// New functions go here // Variables
// Same code as before // Kick things off
buildQuiz(); // Pagination
// New code here // Show the first slide
showSlide(currentSlide); // Event listeners
// New event listeners here

Possiamo iniziare con alcune variabili per memorizzare i riferimenti ai nostri pulsanti di navigazione e tenere traccia di quale diapositiva ci troviamo. Aggiungi questi dopo la chiamata a buildQuiz(), come mostrato sopra:

// Pagination
const previousButton = document.getElementById("previous");
const nextButton = document.getElementById("next");
const slides = document.querySelectorAll(".slide");
let currentSlide = 0;

Quindi scriveremo una funzione per mostrare una diapositiva. Aggiungi questo sotto le funzioni esistenti (buildQuiz ed showResults):

function showSlide(n) { slides[currentSlide].classList.remove('active-slide'); slides[n].classList.add('active-slide'); currentSlide = n; if(currentSlide === 0){ previousButton.style.display = 'none'; } else{ previousButton.style.display = 'inline-block'; } if(currentSlide === slides.length-1){ nextButton.style.display = 'none'; submitButton.style.display = 'inline-block'; } else{ nextButton.style.display = 'inline-block'; submitButton.style.display = 'none'; }
}

Ecco cosa fanno le prime tre righe:

  • Nascondi la diapositiva corrente rimuovendo il active-slide classe.
  • Mostra la nuova diapositiva aggiungendo il active-slide classe.
  • Aggiorna il numero di diapositiva corrente.

Le righe successive introducono la seguente logica:

  • Se siamo sulla prima diapositiva, nascondi il file Diapositiva precedente pulsante. Altrimenti, mostra il pulsante.
  • Se siamo nell'ultima diapositiva, nascondi il file AVANTI pulsante e mostra il Invio pulsante. Altrimenti, mostra il AVANTI e nascondi il pulsante Invio pulsante.

Dopo aver scritto la nostra funzione, possiamo immediatamente chiamare showSlide(0) per mostrare la prima diapositiva. Questo dovrebbe venire dopo il codice di impaginazione:

// Pagination
... showSlide(currentSlide);

Successivamente possiamo scrivere funzioni per far funzionare i pulsanti di navigazione. Questi vanno sotto il showSlide funzione:

function showNextSlide() { showSlide(currentSlide + 1);
} function showPreviousSlide() { showSlide(currentSlide - 1);
}

Qui, stiamo usando il nostro showSlide funzione per consentire ai nostri pulsanti di navigazione di mostrare la diapositiva precedente e la diapositiva successiva.

Infine, dovremo collegare i pulsanti di navigazione a queste funzioni. Questo arriva alla fine del codice:

// Event listeners
...
previousButton.addEventListener("click", showPreviousSlide);
nextButton.addEventListener("click", showNextSlide);

Ora il tuo quiz ha una navigazione funzionante!

Vedi la penna
Quiz JavaScript semplice con impaginazione
di SitePoint (@SitePoint)
on CodePen.

Cosa c'è di nuovo?

Ora che hai un quiz JavaScript di base, è tempo di essere creativi e sperimentare.

Ecco alcuni suggerimenti che puoi provare:

  • Prova diversi modi per rispondere a una risposta corretta o a una risposta sbagliata.
  • Dai uno stile al quiz.
  • Aggiungi una barra di avanzamento.
  • Consenti agli utenti di esaminare le risposte prima di inviare.
  • Fornire agli utenti un riepilogo delle loro risposte dopo l'invio.
  • Aggiorna la navigazione per consentire agli utenti di saltare a qualsiasi numero di domanda.
  • Crea messaggi personalizzati per ogni livello di risultati. Ad esempio, se qualcuno ottiene un punteggio di 8/10 o superiore, chiamalo un ninja quiz.
  • Aggiungi un pulsante per condividere i risultati sui social media.
  • Salva i tuoi punteggi migliori usando localStorage.
  • Aggiungere un conto alla rovescia per vedere se le persone possono battere il tempo.
  • Applica i concetti di questo articolo ad altri usi, come uno stimatore del prezzo del progetto o un quiz sociale "che personaggio sei tu".

Fonte: https://www.sitepoint.com/simple-javascript-quiz/?utm_source=rss

spot_img

L'ultima intelligenza

spot_img