使用 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

相关推荐
奔跑的呱呱牛12 小时前
generate-route-vue基于文件系统的 Vue Router 动态路由生成工具
前端·javascript·vue.js
柳杉12 小时前
从动漫水面到赛博飞船:这位开发者的Three.js作品太惊艳了
前端·javascript·数据可视化
Greg_Zhong12 小时前
前端基础知识实践总结,每日更新一点...
前端·前端基础·每日学习归类
We་ct13 小时前
LeetCode 148. 排序链表:归并排序详解
前端·数据结构·算法·leetcode·链表·typescript·排序算法
TON_G-T13 小时前
day.js和 Moment.js
开发语言·javascript·ecmascript
IT_陈寒13 小时前
JavaScript开发者必看:5个让你的代码性能翻倍的隐藏技巧
前端·人工智能·后端
Irene199113 小时前
JavaScript 中 this 指向总结和箭头函数的作用域说明(附:call / apply / bind 对比总结)
javascript·this·箭头函数
2501_9219308313 小时前
ReactNative项目OpenHarmony三方库集成实战:react-native-appearance(更推荐自带的Appearance)
javascript·react native·react.js
还是大剑师兰特13 小时前
Vue3 中 computed(计算属性)完整使用指南
前端·javascript·vue.js