如何用Vanilla Javascript和Tailwind CSS构建一个测验应用程序

127 阅读8分钟

如何使用Vanilla Javascript和Tailwind CSS构建一个测验应用程序

本教程将向你展示如何在不使用任何Javascript框架的情况下,用HTML、CSS、JavaScript和Tailwind CSS构建一个测验应用。

前提条件

  • 一个好的文本编辑器。
  • 对HTML、CSS和JavaScript有清晰的理解。
  • 安装了Node.js。

开始使用Tailwind CSS

Tailwind CSS是一个基于工具的CSS框架,有助于建立一个独特的、响应式的用户界面。

Tailwind CSS为其用户提供了实用工具,他们可以用来为其应用程序设计独特的用户界面,而不像其他CSS框架,如Bootstrap、Material UI或Materialize,是基于组件的。

将Tailwind CSS添加到你的项目中

首先,你必须在应用程序目录上进行设置。在你的文本编辑器中打开一个空文件夹,并将其命名为tailwindcss ,然后在你的终端运行以下命令,创建一个package.json

npm init -y

接下来,你必须通过在终端运行下面的命令来安装项目所需的依赖项。

npm install -D tailwindcss@latest postcss@latest autoprefixer@latest

之后,在该目录中创建一个新的文件夹,并命名为postcss.config.js 。在其中,复制并粘贴下面的代码。

const cssnano = require("cssnano");
module.exports = {
  plugins: [
    require("tailwindcss"),
    cssnano({
      preset: "default",
    }),
    require("autoprefixer"),
  ],
};

然后运行下面的命令,创建tailwind配置文件。

npx tailwindcss init

接下来,创建一些文件夹。你可以在你的src/css 文件夹中创建一个tailwind.css 文件。在这个文件内复制并粘贴下面的tailwind基础包。

@tailwind base;
@tailwind components;
@tailwind utilities;

现在自定义你的package.json 文件。你可以用下面的代码取代scripts 的配置。

"scripts": {
 "tw:build": "tailwindcss build ./src/css/tailwind.css -o ./public/css/tailwind.css"
}

你的package.json 文件现在将看起来像这样。

{
  "name": "quiz-app-2",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "tw:build": "tailwindcss build ./src/css/tailwind.css -o ./public/css/tailwind.css"
   },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^10.3.7",
    "postcss": "^8.3.9",
    "tailwindcss": "^2.2.16"
  }
}

最后,在你的终端运行下面的命令,然后Tailwind CSS就会在你的应用程序中设置好。

npm run tw:build

你可以在你的public/css 文件夹中创建你的index.html 。你的style.css 将在你的src/css 文件夹中。应用程序的目录可能看起来像这样。

App directory

在这一点上,你已经准备好开始构建你的测验应用程序。

设计测验应用程序

我们的测验应用程序将有一个开始按钮,它将引导你进入问题以及四个选项。正确的答案标签在选择/点击时将变成绿色。其他错误的答案标签在选择时变成红色。

一个next 按钮也会弹出,它将引导用户进入下一个问题和选项页面。

您可以用下面的代码将Tailwind CSS链接到您的HTML。

`<link rel="stylesheet" href="./css/tailwind.css" />`

该应用程序的HTML代码如下所示。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Quiz App with JavaScript</title>
    <link rel="stylesheet" href="../src/css/style.css">
    <link rel="stylesheet" href="./css/tailwind.css">
</head>
<body class="bg-gradient-to-r from-green-400 via-green-600 to-green-800 w-screen h-screen flex justify-center items-center">
    <div class="container">
        <div id="question-container" class="hide">
            <div id="question">Question</div>
            <div id="answer-buttons" class="grid gap-4 grid-cols-2 my-7">
                <button class="btn">Answer 1</button>
                <button class="btn">Answer 2</button>
                <button class="btn">Answer 3</button>
                <button class="btn">Answer 4</button>
            </div>
        </div>
        <div class="flex justify-center gap-4">
            <button id="start-btn" class="bg-pink-700 px-9 py-3 text-white text-2xl rounded-lg hover:bg-pink-400">Start</button>
            <button id="next-btn" class="bg-pink-700 px-9 py-3 text-white text-2xl rounded-lg hover:bg-pink-400">Next</button>
        </div>

        </div>

    </div>
    <script defer src="../src/script.js"></script>
</body>
</html>

在上面的代码中,我们从[Tailwind CSS官方网站]上导入了几个实用程序,用来为几个应用程序组件进行样式设计。另外,问题和答案容器包含了假代码,我们以后会用JavaScript来更新。复制并粘贴这些CSS代码到你的style.css 文件。

在上面的代码中,我们从[Tailwind CSS官方网站]上导入了几个实用工具,我们在为我们应用程序的几个组件设计样式时使用了这些工具。另外,问题和答案容器中包含了假代码,我们以后会用JavaScript进行更新。

复制并粘贴以下CSS代码到你的style.css 文件。

*,
*::before,
*::after {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}

:root {
  --hue-neutral: 200;
  --hue-wrong: 0;
  --hue-correct: 145;
}

.container {
  width: 800px;
  max-width: 80%;
  background-color: white;
  border-radius: 5px;
  padding: 10px;
  box-shadow: 0 0 10px 2px;
}

.btn {
  --hue: var(--hue-neutral);
  border: 1px solid hsl(var(--hue), 100%, 30%);
  background-color: hsl(var(--hue), 100%, 50%);
  border-radius: 5px;
  padding: 5px 10px;
  color: white;
  outline: none;
}

.btn:hover {
  border-color: black;
}

.btn.correct {
  --hue: var(--hue-correct);
  color: black;
}

.btn.wrong {
  --hue: var(--hue-wrong);
}

.hide {
  display: none;
}

上面的代码代表了答案按钮的样式,以及当用户选择答案时,它们对点击的响应性。

注意,我们还设置了一个hide 类到display: none ,我们将在JavaScript中使用它。

这就是应用程序的根页面在这一点上的样子。

Quiz app

添加JavaScript

首先,在你的应用程序目录中创建一个script.js 文件。在那里,你必须用下面的代码将你要处理的HTML元素调用到你的JavaScript中。

const startButton = document.querySelector("#start-btn");
const nextButton = document.querySelector("#next-btn");
const questionContainerElement = document.querySelector("#question-container");
const questionElement = document.querySelector("#question");
const answerButtonsElement = document.querySelector("#answer-buttons");

然后创建一个数组,该数组将包含你的测验问题和它们相应的答案选项。

代码如下所示。

const questions = [
  {
    question: "what is 10 * 2?",
    answers: [
      { text: "102", correct: false },
      { text: "210", correct: false },
      { text: "12", correct: false },
      { text: "20", correct: true },
    ],
  },
  {
    question: "where can you learn how to be a better technical writer?",
    answers: [
      { text: "Zoo", correct: false },
      { text: "Section Eng-Ed", correct: true },
      { text: "At the park", correct: false },
      { text: "None of them", correct: false },
    ],
  },
  {
    question: "Who is the author of this article?",
    answers: [
      { text: "Prince Philips", correct: false },
      { text: "Barrack Obama", correct: false },
      { text: "Doro Onome", correct: true },
      { text: "John Cena", correct: false },
    ],
  },

  {
    question: "Who is the greatest footballer of all time",
    answers: [
      { text: "CR7", correct: true },
      { text: "Zinedine Zidane", correct: false },
      { text: "Ronaldinho", correct: false },
      { text: "Lionel Messi", correct: false },
    ],
  },
];

startQuiz函数

这个函数在你点击开始按钮开始游戏时运行。你将在开始按钮上调用hide 类,使其在用户点击后立即消失。

你将在一个sort() 函数中使用Math.Random() ,以随机显示问题数组中的问题。

这就是startQuiz 函数的作用。

let shuffledQuestions, currentQuestionIndex;

const startQuiz = () => {
  startButton.classList.add("hide");
  shuffledQuestions = questions.sort(() => Math.random() - 0.5);
  currentQuestionIndex = 0;
  questionContainerElement.classList.remove("hide");
  setNextQuestion();
};

现在,给start 按钮添加一个事件监听器,当用户点击该按钮时,它将运行startQuiz 函数。

startButton.addEventListener("click", startQuiz);

SetNextQuestion函数

这个函数将简单地通过调用shuffledQuestions 函数并在其中传递currentQuestionIndex 来随机显示问题。

const setNextQuestion = () => {
  resetState();
  displayQuestion(shuffledQuestions[currentQuestionIndex]);
};

你还需要为next 按钮创建一个事件监听器,这样当用户点击它时,就会显示下一个问题。

我们将通过递增currentQuestionIndex ,并调用setNextQuestion 函数来实现。

nextButton.addEventListener("click", () => {
  currentQuestionIndex++;
  setNextQuestion();
});

displayQuestion函数

现在,我们创建一个displayQuestion ,该函数将显示问题和答案选项。你将用我们先前创建的问题数组中的实际数据替换问题和答案容器中的虚拟文本。

我们将用document.createElement(‘button’) 为答案选项创建一个按钮。这个函数将包含一个条件语句,它将检查答案是否正确。如果是的话,那么它应该调用correct 类。

你还必须为该按钮创建一个事件监听器,并调用我们稍后创建的chooseAnswer 函数。

const displayQuestion = (question) => {
  questionElement.innerText = question.question;
  question.answers.forEach((answer) => {
    const button = document.createElement("button");
    button.innerText = answer.text;
    button.classList.add("btn");
    if (answer.correct) {
      button.dataset.correct = answer.correct;
    }
    button.addEventListener("click", chooseAnswer);
    answerButtonsElement.appendChild(button);
  });
};

resetState函数

这个函数将在每次用户设置新问题时,将与你的表单、问题和正文相关的一切都重置为默认状态。下面是这个函数的代码。

const resetState = () => {
  clearStatusClass(document.body);
  nextButton.classList.add("hide");
  while (answerButtonsElement.firstChild) {
    answerButtonsElement.removeChild(answerButtonsElement.firstChild);
  }
};

在上面的函数中,我们确保了当用户点击一个答案时,就会出现一个next 按钮,而当点击一个新问题时,就会立即消失。

我们需要创建函数,在点击其中一个选项按钮时选择一个答案。

选择答案(selectAnswer)函数

首先,你必须针对用户点击的答案按钮,创建一个这样的变量:const selectedButton = e.target 。然后,你可以得到一个变量correct ,它将等于selectedButton.dataset.correct

接下来,你需要循环浏览其他按钮并为它们设置类。你要从answerButtonsElement.children 创建一个数组。answerButtonsElement.children 返回的是一个活的集合,它自己会更新,所以你必须把它转换成一个数组,以方便循环浏览每个按钮。

然后你调用setStatusClass ,我们将在稍后创建这个函数,并传入button.dataset.correct ,确定所选的答案是否正确。

你也可以使用一个条件语句,如果用户到了最后一个问题,就把next 按钮转换为restart 按钮。一旦点击了restart 按钮,测试就重新开始。下面是chooseAnswer 函数的代码。

const chooseAnswer = (e) => {
  const selectedButton = e.target;
  const correct = selectedButton.dataset.correct;
  Array.from(answerButtonsElement.children).forEach((button) => {
    setStatusClass(button, button.dataset.correct);
  });
  if (shuffledQuestions.length > currentQuestionIndex + 1) {
    nextButton.classList.remove("hide");
  } else {
    startButton.innerText = "Restart";
    startButton.classList.remove("hide");
  }
};

SetStatusClass函数

你需要做的第一件事是调用ClearStatusClass ,我们将在这之后创建这个函数,并传入element 。然后你使用一个条件语句来实际检查所选的答案是否正确。如果是,就添加correct 类,否则就添加wrong 类。

下面是代码。

const setStatusClass = (element, correct) => {
  clearStatusClass(element);
  if (correct) {
    element.classList.add("correct");
  } else {
    element.classList.add("wrong");
  }
};

clearStatusClass 功能代码如下所示。

const clearStatusClass = (element) => {
  element.classList.remove("correct");
  element.classList.remove("wrong");
};

下面是我们的测验应用程序的操作视频。

App gif

结论

在构建测验应用程序时,我们使用ES6类来组织我们的代码。我们使用CSS3和一些Tailwind的CSS工具来设计应用程序。我们还使用了Vanilla JavaScript。

有了这些,你就有了一个功能齐全的测验应用程序。