自己写一个刷题应用 - 用 TypeScript, HTML, CSS 搭建(一)

自己写一个刷题应用 - 用 TypeScript, HTML, CSS 搭建(一)
最新回答
灰尘往事

2020-10-07 15:21:03

使用 TypeScript、HTML 和 CSS 搭建刷题应用(一)

本文将介绍如何使用 TypeScript、HTML 和 CSS 搭建一个基础的刷题应用,实现拖拽(Drag and Drop)类型题目的交互功能。

一、项目初始化与结构搭建

1. 初始化项目

使用 tsc --init 命令初始化 TypeScript 项目,生成 tsconfig.json 文件。

2. 创建项目文件夹结构project/├── src/ // TypeScript 源文件目录│ ├── index.ts // 主入口文件│ └── questionTypes/ // 题目类型相关文件│ └── dragDrop.ts // 拖拽题目类型实现├── scripts/ // 编译后的 JavaScript 文件目录├── index.html // HTML 页面└── styles.css // CSS 样式文件3. 配置 tsconfig.json

在 tsconfig.json 中设置 rootDir 和 outDir 属性,指定 TypeScript 源文件目录和编译输出目录:

{ "compilerOptions": { "rootDir": "./src", "outDir": "./scripts", "target": "ES6", "module": "ES6", "strict": true }}

二、HTML 页面搭建

在 index.html 中创建基本的页面结构,包括题干区域、选项区域和答题区域:

<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="styles.css"> <title>刷题应用</title></head><body> <div class="container"> <h1>刷题应用</h1> <div id="question-stem" class="question-stem"> <!-- 题干将通过 JavaScript 动态插入 --> </div> <div class="question-container"> <div id="options-container" class="options-container"> <!-- 选项将通过 JavaScript 动态插入 --> </div> <div id="answer-container" class="answer-container"> <!-- 答题区域将通过 JavaScript 动态插入 --> </div> </div> <button id="submit-button">提交</button> <div id="result-container" class="result-container"> <!-- 验证结果将通过 JavaScript 动态插入 --> </div> </div> <script src="scripts/index.js"></script></body></html>

三、CSS 样式设计

在 styles.css 中设计页面样式,使页面布局美观且易于交互:

body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f4f4f4;}.container { max-width: 800px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 5px; box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);}h1 { text-align: center;}.question-stem { margin-bottom: 20px; padding: 10px; border: 1px solid #ccc; border-radius: 5px;}.question-container { display: flex; justify-content: space-between; margin-bottom: 20px;}.options-container,.answer-container { width: 45%; min-height: 200px; border: 1px solid #ccc; border-radius: 5px; padding: 10px;}.option-item,.answer-item { padding: 8px; margin-bottom: 5px; border: 1px solid #ddd; border-radius: 3px; cursor: pointer; background-color: #f9f9f9;}.option-item:hover,.answer-item:hover { background-color: #e9e9e9;}#submit-button { display: block; margin: 0 auto; padding: 10px 20px; background-color: #007BFF; color: white; border: none; border-radius: 5px; cursor: pointer;}#submit-button:hover { background-color: #0056b3;}.result-container { margin-top: 20px; padding: 10px; border: 1px solid #ccc; border-radius: 5px; display: none;}

四、TypeScript 实现拖拽题目类型

1. 定义题目数据结构

在 src/questionTypes/dragDrop.ts 中定义拖拽题目的数据结构:

interface DragDropOption { id: number; text: string;}interface DragDropAnswer { id: number; text: string;}interface DragDropQuestion { stem: string; options: DragDropOption[]; correctAnswers: DragDropAnswer[];}2. 实现拖拽功能

在 src/index.ts 中实现拖拽功能,包括选项的拖动和答题区域的更新:

import { DragDropQuestion, DragDropOption, DragDropAnswer } from './questionTypes/dragDrop';// 示例题目数据const question: DragDropQuestion = { stem: "请将以下选项拖动到答题区域,按照正确顺序排列:", options: [ { id: 1, text: "选项 A" }, { id: 2, text: "选项 B" }, { id: 3, text: "选项 C" } ], correctAnswers: [ { id: 1, text: "选项 A" }, { id: 2, text: "选项 B" }, { id: 3, text: "选项 C" } ]};// 获取 DOM 元素const questionStemElement = document.getElementById('question-stem');const optionsContainerElement = document.getElementById('options-container');const answerContainerElement = document.getElementById('answer-container');const submitButtonElement = document.getElementById('submit-button');const resultContainerElement = document.getElementById('result-container');// 渲染题干if (questionStemElement) { questionStemElement.innerHTML = question.stem;}// 渲染选项if (optionsContainerElement) { question.options.forEach((option) => { const optionElement = document.createElement('div'); optionElement.classList.add('option-item'); optionElement.draggable = true; optionElement.textContent = option.text; optionElement.dataset.id = option.id.toString(); optionElement.addEventListener('dragstart', (e) => { e.dataTransfer?.setData('text/plain', optionElement.dataset.id); }); optionsContainerElement.appendChild(optionElement); });}// 处理拖放事件if (answerContainerElement) { answerContainerElement.addEventListener('dragover', (e) => { e.preventDefault(); }); answerContainerElement.addEventListener('drop', (e) => { e.preventDefault(); const id = e.dataTransfer?.getData('text/plain'); if (id) { const optionElements = document.querySelectorAll('.option-item'); optionElements.forEach((element) => { if (element.dataset.id === id &&!element.classList.contains('dragging')) { const newAnswerElement = document.createElement('div'); newAnswerElement.classList.add('answer-item'); newAnswerElement.textContent = element.textContent; newAnswerElement.dataset.id = id; // 添加点击事件,用于将选项移回左边 newAnswerElement.addEventListener('click', () => { newAnswerElement.remove(); // 这里可以添加逻辑将选项重新放回原来的位置(简单起见,这里不实现完整逻辑) }); answerContainerElement.appendChild(newAnswerElement); element.classList.add('dragging'); } }); } });}// 处理提交按钮点击事件if (submitButtonElement && answerContainerElement && resultContainerElement) { submitButtonElement.addEventListener('click', () => { const answerItems = document.querySelectorAll('.answer-item'); const userAnswers: DragDropAnswer[] = []; answerItems.forEach((item) => { const text = item.textContent; const id = parseInt(item.dataset.id); if (text &&!isNaN(id)) { userAnswers.push({ id, text }); } }); let isCorrect = true; if (userAnswers.length === question.correctAnswers.length) { for (let i = 0; i < userAnswers.length; i++) { if ( userAnswers[i].id!== question.correctAnswers[i].id || userAnswers[i].text!== question.correctAnswers[i].text ) { isCorrect = false; break; } } } else { isCorrect = false; } if (isCorrect) { resultContainerElement.textContent = "回答正确!"; } else { resultContainerElement.textContent = "回答错误,请重新尝试。"; } resultContainerElement.style.display = 'block'; });}

五、编译与运行

1. 编译 TypeScript 代码

在项目根目录下运行 tsc 命令,将 TypeScript 代码编译为 JavaScript 代码,输出到 scripts 文件夹。

2. 运行应用

在浏览器中打开 index.html 文件,即可看到刷题应用的界面,并可以进行拖拽题目的交互操作。

(此处应插入应用界面截图,由于无法直接获取,你可自行运行代码后截图替换该链接)

六、总结

本文通过使用 TypeScript、HTML 和 CSS 搭建了一个基础的刷题应用,实现了拖拽类型题目的交互功能。通过定义题目数据结构、实现拖拽逻辑和验证结果,为后续扩展更多题目类型和功能奠定了基础。后续可以继续完善应用,例如添加更多题目类型、实现题目数据的动态加载、增加错题统计等功能。