使用 HTML + JavaScript 实现在线知识挑战

文章目录

一、在线知识挑战

在线知识挑战系统为用户提供了一个互动性强、反馈及时的学习体验平台。通过倒计时机制增加紧张感,即时结果显示正确答案帮助用户学习,得分统计激发用户的竞争心理。这种系统特别适用于教育应用、技能评估或娱乐类游戏。

本文将介绍如何使用 HTML、CSS 和 JavaScript 实现一个完整的知识挑战系统。

二、效果演示

这个知识挑战系统具有完整的交互流程:用户点击"开始答题"按钮进入挑战界面,系统展示第一道题目并启动 30 秒倒计时。用户可以选择答案选项,系统立即显示正确或错误状态,并在 1 秒后自动跳转到下一题。当时间耗尽而未作答时,系统会标记正确答案并自动跳转。完成后,系统显示总得分和鼓励信息,用户可以选择重新挑战。


三、系统分析

1、页面结构

页面主要包括以下部分:

1.1 开始界面

包含标题、说明文字和开始按钮,引导用户进入挑战。

html 复制代码
<div class="start-screen" id="startScreen">
    <h2>欢迎参加在线知识挑战</h2>
    <p>本挑战包含 <span id="totalQuestions">0</span> 道题目,每题100金币</p>
    <p>每题限时30秒,答对获得100金币,祝您好运!</p>
    <button class="btn" onclick="startQuiz()">开始答题</button>
</div>

1.2 题目容器

包含圆形倒计时器和题目卡片,显示当前题目和可选择的答案。

html 复制代码
<div class="quiz-container hidden" id="quizContainer">
    <div id="timer" class="circular-timer">
        <svg width="70" height="70" viewBox="0 0 70 70">
            <circle class="circle-bg" cx="35" cy="35" r="30"></circle>
            <circle class="circle" cx="35" cy="35" r="30" stroke-dasharray="188.5" stroke-dashoffset="0" id="timerCircle"></circle>
        </svg>
        <div class="timer-center" id="timerText">30</div>
    </div>

    <div class="question-card" id="questionCard">
        <div class="question-header">
            <div class="question-counter" id="questionCounter">1 / 10</div>
            <div class="question-text" id="questionText"></div>
        </div>
        <div class="options" id="optionsContainer"></div>
    </div>
</div>

1.3 结果界面

显示最终得分和鼓励信息,提供重新开始的选项。

html 复制代码
<div class="result-screen hidden" id="resultScreen">
    <h2>答题完成!</h2>
    <div class="score-display">
        <div class="score-number" id="finalScore">0金币</div>
        <div class="result-message" id="resultMessage"></div>
    </div>
    <button class="btn" onclick="restartQuiz()">重新答题</button>
</div>

2、核心功能实现

系统通过全局变量维护挑战状态,包括当前题目索引、得分、用户答案记录和计时器。startQuiz 函数负责重置这些变量并切换到题目界面。

javascript 复制代码
let currentQuestion = 0;
let score = 0;
let answers = [];
const timeLimit = 30;
let timer = null;
javascript 复制代码
function startQuiz() {
    startScreen.classList.add('hidden');
    quizContainer.classList.remove('hidden');
    currentQuestion = 0;
    score = 0;
    answers = new Array(questions.length).fill(null);

    displayQuestion();
    startTimer();
}

2.1 圆形倒计时实现

使用 SVG 圆形元素创建视觉化的倒计时效果,通过修改 stroke-dashoffset 属性控制圆弧长度,同时改变颜色以提示剩余时间。

javascript 复制代码
function startTimer() {
    clearInterval(timer);
    let timeLeft = timeLimit;
    const radius = 30;
    const circumference = 2 * Math.PI * radius;

    timerCircle.style.strokeDasharray = circumference;
    timerCircle.style.strokeDashoffset = 0;
    timerCircle.style.stroke = '#3b82f6';
    timerText.textContent = timeLeft.toString();

    const initialOffset = (timeLeft / timeLimit) * circumference;
    timerCircle.style.strokeDashoffset = circumference - initialOffset;

    timer = setInterval(() => {
        timeLeft--;

        if (timeLeft <= 0) {
            handleTimeout();
            return;
        }

        const offset = (timeLeft / timeLimit) * circumference;
        timerCircle.style.strokeDashoffset = circumference - offset;
        timerText.textContent = timeLeft.toString();

        if (timeLeft <= 10) {
            timerCircle.style.stroke = '#ef4444';
            timerText.style.color = '#ef4444';
        }
    }, 1000);
}

2.2 题目渲染与交互

displayQuestion 函数根据当前题目数据渲染选项,并处理用户交互逻辑。它会根据用户是否已作答来决定显示样式和交互行为。

javascript 复制代码
function displayQuestion() {
    const q = questions[currentQuestion];
    const userAnswer = answers[currentQuestion];

    questionText.textContent = q.question;
    questionCounter.textContent = `${currentQuestion + 1} / ${questions.length}`;

    optionsContainer.innerHTML = '';
    q.options.forEach((option, index) => {
        const el = document.createElement('div');
        el.className = 'option';

        if (userAnswer === null) {
            el.onclick = () => selectOption(index);
        }

        if (userAnswer !== null) {
            if (userAnswer === index) {
                el.classList.add('selected');
                if (userAnswer === q.correct) el.classList.add('correct');
                else el.classList.add('incorrect');
            }
            if (index === q.correct && userAnswer !== q.correct) {
                el.classList.add('correct');
            }
        }

        el.innerHTML = `<span class="option-letter">${String.fromCharCode(65 + index)}</span>${option}`;
        optionsContainer.appendChild(el);
    });
}

2.3 答案处理与导航

selectOption 函数处理用户选择,验证答案正确性并更新得分,然后延迟跳转到下一题。goToNextQuestion 函数管理题目间的导航逻辑。

javascript 复制代码
function selectOption(optionIndex) {
    if (answers[currentQuestion] !== null) return;

    clearInterval(timer);
    answers[currentQuestion] = optionIndex;
    const q = questions[currentQuestion];
    const options = optionsContainer.querySelectorAll('.option');

    options.forEach((el, index) => {
        el.classList.remove('selected', 'correct', 'incorrect');

        if (index === optionIndex) {
            el.classList.add('selected');
            if (optionIndex === q.correct) {
                el.classList.add('correct');
                score += 100;
            } else {
                el.classList.add('incorrect');
            }
        }
        if (index === q.correct && optionIndex !== q.correct) {
            el.classList.add('correct');
        }
    });

    setTimeout(goToNextQuestion, 1000);
}
javascript 复制代码
function goToNextQuestion() {
    if (currentQuestion < questions.length - 1) {
        currentQuestion++;
        displayQuestion();
        startTimer();
    } else {
        endQuiz();
    }
}

四、扩展建议

  • 添加难度等级选择功能,调整题目数量和时间限制
  • 实现用户登录系统,保存历史得分和排名
  • 增加音效反馈,提升用户体验的沉浸感

五、源码地址

git地址:https://gitee.com/ironpro/hjdemo/blob/master/quiz/index.html

相关推荐
薛定谔的猫22 小时前
Cursor 系列(3):关于MCP
前端·cursor·mcp
sheji34162 小时前
【开题答辩全过程】以 基于web的拍卖系统设计与实现为例,包含答辩的问题和答案
前端
明月_清风2 小时前
模仿 create-vite / create-vue 风格写一个现代脚手架
前端·后端
aou2 小时前
让表格式录入像 Excel 一样顺滑
前端·ai编程
前端付豪2 小时前
必知 Express和 MVC
前端·node.js·全栈
重铸码农荣光2 小时前
CSS 也能“私有化”?揭秘模块化 CSS 的防坑指南(附 Vue & React 实战)
前端·css·vue.js
南囝coding2 小时前
CSS终于能做瀑布流了!三行代码搞定,告别JavaScript布局
前端·后端·面试
ccnocare2 小时前
git 创建远程分支
前端
全栈王校长2 小时前
Vue.js 3 项目构建神器:Webpack 全攻略
前端