<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
<title>智能题库刷题系统</title>
<style>
/* 自定义样式 */
#side-nav {
position: fixed;
right: -240px;
top: 120px;
width: 240px;
max-height: 80vh;
overflow-y: auto;
background: white;
padding: 15px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
transition: right 0.3s ease;
}
#side-nav.open {
right: 20px;
}
.question-btn {
width: 40px;
height: 40px;
margin: 4px;
transition: all 0.3s;
}
.answered-correct {
background-color: #4CAF50 !important;
color: white !important;
}
.answered-wrong {
background-color: #f44336 !important;
color: white !important;
}
.current-question {
box-shadow: 0 0 0 2px #2196F3;
}
.blink-border {
animation: blinkBorder 1s linear infinite;
}
@keyframes blinkBorder {
50% {
border-color: transparent;
}
}
#drop-area.dragover {
border-color: #2196F3;
background-color: #f0f9ff;
}
.question-image {
max-width: 300px;
max-height: 200px;
cursor: zoom-in;
border-radius: 8px;
}
/* 新增折叠按钮样式 */
#toggle-nav {
position: fixed;
right: 20px;
top: 120px;
background: white;
padding: 10px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
cursor: pointer;
z-index: 10;
}
/* 错题解析样式 */
#wrong-answer-explanation {
display: none;
background: white;
padding: 15px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
margin-top: 20px;
}
/* 结束答题按钮样式 */
#end-exam-btn {
background-color: #FF9800;
color: white;
padding: 10px 20px;
border-radius: 8px;
margin-top: 20px;
cursor: pointer;
}
/* 结束答题后错题解析显示区域样式 */
#end-exam-explanation {
display: none;
background: white;
padding: 15px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
margin-top: 20px;
}
/* 新增闪烁框样式 */
.correct-answer-blink {
border: 2px solid red;
animation: blinkBorder 1s linear infinite;
}
/* 模态框样式 */
#image-modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.9);
}
#modal-image {
margin: auto;
display: block;
max-width: 90%;
max-height: 90%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: 0.3s;
object-fit: contain; /* 确保图片按比例缩放 */
}
#close-modal {
position: absolute;
top: 15px;
right: 35px;
color: #f1f1f1;
font-size: 40px;
font-weight: bold;
transition: 0.3s;
}
#close-modal:hover,
#close-modal:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
</style>
</head>
<body class="bg-gray-50">
<!-- 控制面板 -->
<div class="container mx-auto p-6" style="margin-right: 280px;">
<!-- 标题 -->
<h1 class="text-3xl font-bold text-center mb-8 text-blue-600">智能题库刷题系统</h1>
<!-- 文件拖放区 -->
<div id="drop-area" class="border-2 border-dashed border-gray-300 rounded-xl p-6 mb-6 text-center">
<p class="text-gray-600">拖放.xlsx文件至此或<label class="text-blue-600 cursor-pointer">点击选择文件
<input type="file" id="file-input" hidden accept=".xlsx">
</label></p>
</div>
<!-- 控制栏 -->
<div class="flex flex-wrap gap-4 mb-6">
<button onclick="exportQuestions()" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg transition-colors">
<i class="fas fa-download mr-2"></i>导出题库
</button>
<button onclick="toggleWrongMode()" id="wrong-mode-btn" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg transition-colors">
<i class="fas fa-bolt mr-2"></i>错题模式
</button>
<button onclick="resetProgress()" class="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg transition-colors">
<i class="fas fa-sync-alt mr-2"></i>重置进度
</button>
<select id="category-filter" onchange="filterQuestions()" class="bg-white border border-gray-300 rounded-lg px-4 py-2">
<option value="">所有分类</option>
</select>
<!-- 修改此处标签文字 -->
<label class="flex items-center space-x-2">
<input type="checkbox" id="blink-switch" checked onchange="toggleBlinkHighlight()">
<span>答案闪烁</span>
</label>
<!-- 新增输入框用于自定义闪烁秒数 -->
<label class="flex items-center space-x-2">
<input type="number" id="blink-duration" value="1" min="1" class="w-16 p-1 border border-gray-300 rounded">
<span>闪烁秒数</span>
</label>
</div>
<!-- 题目容器 -->
<div id="question-container" class="bg-white rounded-xl shadow-lg p-6 mb-6">
<div class="flex justify-between items-center mb-4">
<span id="question-number" class="text-lg font-semibold text-gray-700"></span>
<span id="progress-status" class="text-sm text-gray-500"></span>
</div>
<div id="question-content" class="mb-4">
<p id="question-text" class="text-lg mb-4"></p>
<img id="question-image" class="question-image mb-4" src="" alt="" style="display: none;">
<div id="options-container" class="space-y-3"></div>
</div>
<div class="flex flex-wrap gap-3 mt-6">
<button onclick="prevQuestion()" class="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg transition-colors">
<i class="fas fa-chevron-left mr-2"></i>上一题
</button>
<button onclick="submitAnswer()" class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-lg transition-colors">
<i class="fas fa-check-circle mr-2"></i>提交答案
</button>
<button onclick="nextQuestion()" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg transition-colors">
下一题<i class="fas fa-chevron-right ml-2"></i>
</button>
</div>
</div>
<!-- 错题解析 -->
<div id="wrong-answer-explanation">
<h2 class="text-xl font-bold mb-2">错题解析</h2>
<p id="explanation-text"></p>
</div>
<!-- 结束答题按钮 -->
<button id="end-exam-btn" onclick="endExam()">结束答题</button>
<!-- 统计信息 -->
<div class="bg-white rounded-xl shadow-lg p-6">
<div class="grid grid-cols-3 gap-4 text-center">
<div class="p-3 bg-green-100 rounded-lg">
<p class="text-sm text-gray-600">正确</p>
<p id="correct-count" class="text-2xl font-bold text-green-600">0</p>
</div>
<div class="p-3 bg-red-100 rounded-lg">
<p class="text-sm text-gray-600">错误</p>
<p id="wrong-count" class="text-2xl font-bold text-red-600">0</p>
</div>
<div class="p-3 bg-blue-100 rounded-lg">
<p class="text-sm text-gray-600">剩余</p>
<p id="remaining-count" class="text-2xl font-bold text-blue-600">0</p>
</div>
</div>
</div>
<!-- 结束答题后错题解析显示区域 -->
<div id="end-exam-explanation">
<h2 class="text-xl font-bold mb-2">结束答题 - 错题解析</h2>
<div id="end-exam-explanation-text"></div>
</div>
</div>
<!-- 折叠按钮 -->
<div id="toggle-nav">
<i class="fas fa-bars"></i>
</div>
<!-- 右侧导航 -->
<div id="side-nav" class="open">
<div class="p-4 border-b">
<input type="text" id="search-input" placeholder="搜索题号..." class="w-full px-3 py-2 border rounded-lg">
</div>
<div class="p-4 grid grid-cols-5 gap-2" id="question-nav"></div>
</div>
<!-- 模态框 -->
<div id="image-modal">
<span id="close-modal">×</span>
<img id="modal-image" src="">
</div>
<script>
// 状态管理
let state = {
questions: [],
currentIndex: 0,
questionStatus: {},
wrongMode: false,
filteredQuestions: [],
categories: new Set(),
blinkHighlight: true, // 新增状态用于控制正确答案闪烁功能
blinkDuration: 1 // 新增状态用于存储闪烁秒数
};
// 初始化
function init() {
bindEvents();
loadSampleQuestions();
const sideNav = document.getElementById('side-nav');
sideNav.classList.add('open');
}
// 绑定事件
function bindEvents() {
// 文件拖放
const dropArea = document.getElementById('drop-area');
dropArea.ondragover = (e) => {
e.preventDefault();
dropArea.classList.add('dragover');
};
dropArea.ondragleave = () => dropArea.classList.remove('dragover');
dropArea.ondrop = (e) => {
e.preventDefault();
dropArea.classList.remove('dragover');
handleFile(e.dataTransfer.files[0]);
};
// 文件选择
document.getElementById('file-input').onchange = (e) => handleFile(e.target.files[0]);
// 快捷键
document.onkeydown = (e) => {
if (e.key >= 'A' && e.key <= 'H') handleNumberKey(e.key);
if (e.key === 'Enter') submitAnswer();
if (e.key === 'ArrowUp') prevQuestion();
if (e.key === 'ArrowDown') nextQuestion();
if (e.key === '9') randomQuestion();
};
// 题号搜索
document.getElementById('search-input').oninput = searchQuestions;
// 折叠按钮事件
document.getElementById('toggle-nav').onclick = toggleNav;
// 新增开关事件
document.getElementById('blink-switch').onchange = toggleBlinkHighlight;
// 新增输入框事件
document.getElementById('blink-duration').oninput = updateBlinkDuration;
// 图片点击事件
const questionImage = document.getElementById('question-image');
questionImage.onclick = openModal;
// 模态框关闭事件
const closeModal = document.getElementById('close-modal');
closeModal.onclick = closeModalHandler;
// 模态框图片点击关闭事件
const modalImage = document.getElementById('modal-image');
modalImage.onclick = closeModalHandler;
// 模态框鼠标滚轮事件
const imageModal = document.getElementById('image-modal');
imageModal.addEventListener('wheel', wheelHandler);
}
// 核心功能函数
function handleFile(file) {
if (!file) return;
const reader = new FileReader();
reader.onload = (e) => {
const data = new Uint8Array(e.target.result);
const workbook = XLSX.read(data, { type: 'array' });
const worksheet = workbook.Sheets[workbook.SheetNames[0]];
const jsonData = XLSX.utils.sheet_to_json(worksheet);
state.questions = jsonData.map((item, index) => ({
_id: Date.now() + index,
题目内容: item.题目内容,
选项: parseOptions(item),
答案: item.答案.split(','),
题目类型: item.题目类型 || 'single',
题目类目: item.题目类目 || '默认类目',
图片路径: item.图片路径 || '',
解析: item.解析 || '' // 新增解析字段
}));
initCategories();
filterQuestions();
updateUI();
};
reader.readAsArrayBuffer(file);
}
function parseOptions(item) {
return Object.entries(item).reduce((acc, [key, value]) => {
if (/^[A-H]$/.test(key)) acc[key] = value;
return acc;
}, {});
}
function initCategories() {
state.categories = new Set(state.questions.map(q => q.题目类目));
const filter = document.getElementById('category-filter');
filter.innerHTML = '<option value="">所有分类</option>';
state.categories.forEach(cat => {
const option = document.createElement('option');
option.value = cat;
option.textContent = cat;
filter.appendChild(option);
});
}
function filterQuestions() {
const category = document.getElementById('category-filter').value;
state.filteredQuestions = state.questions.filter(q => {
const matchCategory =!category || q.题目类目 === category;
return state.wrongMode?
matchCategory && state.questionStatus[q._id] &&!state.questionStatus[q._id].correct :
matchCategory;
});
state.currentIndex = 0;
updateUI();
}
function updateUI() {
updateQuestion();
updateNavigation();
updateStats();
}
function updateQuestion() {
const question = state.filteredQuestions[state.currentIndex];
if (!question) return;
document.getElementById('question-number').textContent = `第 ${state.currentIndex + 1} 题 / 共 ${state.filteredQuestions.length} 题`;
document.getElementById('question-text').textContent = question.题目内容;
const optionsContainer = document.getElementById('options-container');
optionsContainer.innerHTML = '';
switch (question.题目类型) {
case 'single':
case 'multiple':
Object.entries(question.选项).forEach(([key, value]) => {
const div = document.createElement('div');
div.className = 'flex items-center space-x-3';
div.innerHTML = `
<input type="${question.题目类型 === 'single'? 'radio' : 'checkbox'}"
id="option-${key}"
name="answer"
value="${key}"
class="w-5 h-5">
<label for="option-${key}" class="text-lg">${key}. ${value}</label>
`;
optionsContainer.appendChild(div);
});
break;
case 'fill':
optionsContainer.innerHTML = `
<input type="text"
id="fill-answer"
class="w-full p-3 border rounded-lg focus:ring-2 focus:ring-blue-500"
placeholder="请输入答案...">
`;
break;
case 'judge':
optionsContainer.innerHTML = `
<div class="flex space-x-4">
<div class="flex items-center">
<input type="radio" id="option-true" name="answer" value="1" class="w-5 h-5">
<label for="option-true" class="ml-2 text-lg">正确</label>
</div>
<div class="flex items-center">
<input type="radio" id="option-false" name="answer" value="0" class="w-5 h-5">
<label for="option-false" class="ml-2 text-lg">错误</label>
</div>
</div>
`;
break;
}
// 显示图片
const imgElement = document.getElementById('question-image');
if (question.图片路径) {
imgElement.style.display = 'block';
imgElement.src = question.图片路径;
} else {
imgElement.style.display = 'none';
}
}
function submitAnswer() {
const question = state.filteredQuestions[state.currentIndex];
if (!question) return;
let userAnswer = getSelectedAnswers(question.题目类型);
if (!userAnswer.length) return alert('请选择答案');
const isCorrect = checkAnswer(question, userAnswer);
updateQuestionStatus(question._id, isCorrect, userAnswer);
handleAnswerFeedback(isCorrect, question, userAnswer);
if (state.wrongMode && isCorrect) {
state.filteredQuestions = state.filteredQuestions.filter(q => q._id!== question._id);
if (state.currentIndex >= state.filteredQuestions.length) {
state.currentIndex = Math.max(0, state.filteredQuestions.length - 1);
}
}
if (state.currentIndex < state.filteredQuestions.length - 1) {
if (!isCorrect) {
setTimeout(() => {
state.currentIndex++;
updateUI();
}, state.blinkDuration * 1000);
} else {
state.currentIndex++;
updateUI();
}
} else {
alert('已经是最后一题了!');
}
if (!isCorrect && state.blinkHighlight) {
showExplanation(question, userAnswer);
}
}
function getSelectedAnswers(type) {
switch (type) {
case 'single':
case 'judge':
return [document.querySelector('input[name="answer"]:checked')?.value].filter(Boolean);
case 'multiple':
return Array.from(document.querySelectorAll('input[name="answer"]:checked')).map(i => i.value);
case 'fill':
return [document.getElementById('fill-answer').value.trim()];
default:
return [];
}
}
function checkAnswer(question, userAnswer) {
return JSON.stringify(userAnswer.sort()) === JSON.stringify(question.答案.sort());
}
function updateQuestionStatus(id, isCorrect, userAnswer) {
state.questionStatus[id] = {
correct: isCorrect,
timestamp: Date.now(),
userAnswer: userAnswer
};
updateStats();
if (state.wrongMode) {
filterQuestions();
}
}
function updateStats() {
const total = state.questions.length;
const correct = Object.values(state.questionStatus).filter(s => s.correct).length;
document.getElementById('correct-count').textContent = correct;
document.getElementById('wrong-count').textContent = Object.keys(state.questionStatus).length - correct;
document.getElementById('remaining-count').textContent = total - Object.keys(state.questionStatus).length;
}
function updateNavigation() {
const nav = document.getElementById('question-nav');
nav.innerHTML = '';
const questionsToShow = state.wrongMode?
state.questions.filter(q => state.questionStatus[q._id] &&!state.questionStatus[q._id].correct) :
state.questions;
questionsToShow.forEach((q, index) => {
const btn = document.createElement('button');
btn.className = 'question-btn rounded-lg bg-gray-200 hover:bg-gray-300';
btn.textContent = state.questions.indexOf(q) + 1;
if (state.questionStatus[q._id]) {
btn.classList.add(state.questionStatus[q._id].correct? 'answered-correct' : 'answered-wrong');
}
if (q._id === state.filteredQuestions[state.currentIndex]?._id) {
btn.classList.add('current-question');
}
btn.onclick = () => {
const targetIndex = state.filteredQuestions.findIndex(fq => fq._id === q._id);
if (targetIndex > -1) {
state.currentIndex = targetIndex;
updateUI();
}
};
nav.appendChild(btn);
});
}
// 其他功能
function toggleWrongMode() {
state.wrongMode =!state.wrongMode;
document.getElementById('wrong-mode-btn').classList.toggle('bg-red-500', state.wrongMode);
document.getElementById('wrong-mode-btn').classList.toggle('bg-gray-500',!state.wrongMode);
filterQuestions();
}
function resetProgress() {
state.questionStatus = {};
state.wrongMode = false;
const endExamExplanation = document.getElementById('end-exam-explanation');
endExamExplanation.style.display = 'none';
filterQuestions();
}
function searchQuestions() {
const searchTerm = document.getElementById('search-input').value.toLowerCase();
const navButtons = document.querySelectorAll('#question-nav button');
navButtons.forEach((btn, index) => {
btn.style.display = (index + 1).toString().includes(searchTerm)? 'block' : 'none';
});
}
function prevQuestion() {
if (state.currentIndex > 0) {
state.currentIndex--;
updateUI();
} else {
alert('已经是第一题了!');
}
}
function nextQuestion() {
if (state.currentIndex < state.filteredQuestions.length - 1) {
state.currentIndex++;
updateUI();
} else {
alert('已经是最后一题了!');
}
}
// 初始化示例题库,添加图片路径
function loadSampleQuestions() {
state.questions = [
{
_id: 1,
题目内容: "JavaScript是什么类型的语言?",
选项: { A: "编译型", B: "解释型", C: "混合型" },
答案: ["B"],
题目类型: "single",
题目类目: "编程基础",
图片路径: "https://picsum.photos/200/300", // 添加图片路径
解析: "JavaScript是一种解释型语言,它在运行时逐行解释代码,而不需要预先编译。"
},
{
_id: 2,
题目内容: "以下哪些是数据库管理系统?",
选项: { A: "MySQL", B: "MongoDB", C: "Redis" },
答案: ["A", "B", "C"],
题目类型: "multiple",
题目类目: "数据库",
图片路径: "https://picsum.photos/200/300/?blur", // 添加图片路径
解析: "MySQL是关系型数据库管理系统,MongoDB是文档型数据库管理系统,Redis是键值对数据库管理系统,它们都属于数据库管理系统。"
},
{
_id: 3,
题目内容: "HTML代表的是______。",
选项: {},
答案: ["超文本标记语言"],
题目类型: "fill",
题目类目: "编程基础",
图片路径: "https://picsum.photos/200/300/?blur=4", // 添加图片路径
解析: "HTML的全称是HyperText Markup Language,即超文本标记语言。"
},
{
_id: 4,
题目内容: "CSS是用于描述网页样式和布局的语言。",
选项: {},
答案: ["1"],
题目类型: "judge",
题目类目: "编程基础",
图片路径: "https://picsum.photos/200", // 添加图片路径
解析: "CSS(Cascading Style Sheets)的主要作用就是定义网页的样式和布局。"
}
];
filterQuestions();
}
// 折叠导航栏
function toggleNav() {
const sideNav = document.getElementById('side-nav');
sideNav.classList.toggle('open');
}
// 显示错题解析
function showExplanation(question, userAnswer) {
const explanationDiv = document.getElementById('wrong-answer-explanation');
const explanationText = document.getElementById('explanation-text');
const userAnsStr = userAnswer.map(ans => question.选项[ans] || ans).join(', ');
const correctAnsStr = question.答案.map(ans => question.选项[ans] || ans).join(', ');
const text = `你的答案:${userAnsStr},正确答案:${correctAnsStr}。`;
explanationText.textContent = text;
explanationDiv.style.display = 'block';
setTimeout(() => explanationDiv.style.display = 'none', state.blinkDuration * 1000); // 根据自定义秒数隐藏解析
}
// 结束答题功能
function endExam() {
const wrongQuestions = state.questions.filter(q => state.questionStatus[q._id] &&!state.questionStatus[q._id].correct);
const explanationDiv = document.getElementById('end-exam-explanation');
const explanationTextDiv = document.getElementById('end-exam-explanation-text');
if (wrongQuestions.length === 0) {
alert('你没有错题,很棒!');
explanationDiv.style.display = 'none';
} else {
let allExplanations = '';
wrongQuestions.forEach((q, index) => {
const userAns = state.questionStatus[q._id].userAnswer;
const userAnsStr = userAns? userAns.map(ans => q.选项[ans] || ans).join(', ') : '未作答';
const correctAnsStr = q.答案.map(ans => q.选项[ans] || ans).join(', ');
allExplanations += `<p>第 ${index + 1} 题:${q.题目内容}</p><p>你的答案:${userAnsStr},正确答案:${correctAnsStr}。${q.解析}</p><hr>`;
});
explanationTextDiv.innerHTML = allExplanations;
explanationDiv.style.display = 'block';
}
}
// 导出题库功能
function exportQuestions() {
const ws = XLSX.utils.json_to_sheet(state.questions.map(q => {
const options = Object.entries(q.选项).reduce((acc, [key, value]) => {
acc[key] = value;
return acc;
}, {});
return {
题目内容: q.题目内容,
...options,
答案: q.答案.join(','),
题目类型: q.题目类型,
题目类目: q.题目类目,
图片路径: q.图片路径,
解析: q.解析
};
}));
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, '题库');
XLSX.writeFile(wb, '题库.xlsx');
}
// 处理数字键选择答案
function handleNumberKey(key) {
const question = state.filteredQuestions[state.currentIndex];
if (!question) return;
switch (question.题目类型) {
case 'single':
case 'judge':
if (question.题目类型 === 'judge' && key === 'B') {
key = '0';
}
const radio = document.getElementById(`option-${key}`);
if (radio) {
radio.checked = true;
}
break;
case 'multiple':
const checkbox = document.getElementById(`option-${key}`);
if (checkbox) {
checkbox.checked =!checkbox.checked;
}
break;
}
}
// 随机一题功能
function randomQuestion() {
if (state.filteredQuestions.length > 0) {
const randomIndex = Math.floor(Math.random() * state.filteredQuestions.length);
state.currentIndex = randomIndex;
updateUI();
}
}
// 处理答案反馈
function handleAnswerFeedback(isCorrect, question, userAnswer) {
if (!isCorrect && state.blinkHighlight && ['single', 'multiple', 'judge'].includes(question.题目类型)) {
question.答案.forEach(ans => {
const label = document.querySelector(`label[for="option-${ans}"]`);
if (label) {
label.classList.add('correct-answer-blink');
setTimeout(() => label.classList.remove('correct-answer-blink'), state.blinkDuration * 1000); // 根据自定义秒数停止闪烁
}
});
}
}
// 切换正确答案闪烁开关
function toggleBlinkHighlight() {
state.blinkHighlight = document.getElementById('blink-switch').checked;
}
// 更新闪烁秒数
function updateBlinkDuration() {
const input = document.getElementById('blink-duration');
const value = parseInt(input.value);
if (!isNaN(value) && value >= 1) {
state.blinkDuration = value;
} else {
input.value = state.blinkDuration;
}
}
// 打开模态框
function openModal() {
const modal = document.getElementById('image-modal');
const modalImage = document.getElementById('modal-image');
const questionImage = document.getElementById('question-image');
modal.style.display = 'block';
modalImage.src = questionImage.src;
}
// 关闭模态框
function closeModalHandler() {
const modal = document.getElementById('image-modal');
modal.style.display = 'none';
}
// 鼠标滚轮事件处理
function wheelHandler(e) {
e.preventDefault();
const modalImage = document.getElementById('modal-image');
// 调整缩放因子以加快缩放速度
const scaleFactor = e.deltaY > 0? 0.8 : 1.2;
const currentWidth = modalImage.offsetWidth;
const currentHeight = modalImage.offsetHeight;
const newWidth = currentWidth * scaleFactor;
const newHeight = currentHeight * scaleFactor;
const maxWidth = window.innerWidth * 0.9;
const maxHeight = window.innerHeight * 0.9;
if (newWidth > 0 && newHeight > 0 && newWidth <= maxWidth && newHeight <= maxHeight) {
modalImage.style.width = newWidth + 'px';
modalImage.style.height = newHeight + 'px';
}
}
// 启动系统
window.onload = init;
</script>
</body>
<!-- 网页鼠标点击特效(爱心) -->
<script type="text/javascript">
! function (e, t, a) {
function r() {
for (var e = 0; e < s.length; e++) s[e].alpha <= 0 ? (t.body.removeChild(s[e].el), s.splice(e, 1)) : (s[
e].y--, s[e].scale += .004, s[e].alpha -= .013, s[e].el.style.cssText = "left:" + s[e].x +
"px;top:" + s[e].y + "px;opacity:" + s[e].alpha + ";transform:scale(" + s[e].scale + "," + s[e]
.scale + ") rotate(45deg);background:" + s[e].color + ";z-index:99999");
requestAnimationFrame(r)
}
function n() {
var t = "function" == typeof e.onclick && e.onclick;
e.onclick = function (e) {
t && t(), o(e)
}
}
function o(e) {
var a = t.createElement("div");
a.className = "heart", s.push({
el: a,
x: e.clientX - 5,
y: e.clientY - 5,
scale: 1,
alpha: 1,
color: c()
}), t.body.appendChild(a)
}
function i(e) {
var a = t.createElement("style");
a.type = "text/css";
try {
a.appendChild(t.createTextNode(e))
} catch (t) {
a.styleSheet.cssText = e
}
t.getElementsByTagName("head")[0].appendChild(a)
}
function c() {
return "rgb(" + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + "," + ~~(255 * Math
.random()) + ")"
}
var s = [];
e.requestAnimationFrame = e.requestAnimationFrame || e.webkitRequestAnimationFrame || e
.mozRequestAnimationFrame || e.oRequestAnimationFrame || e.msRequestAnimationFrame || function (e) {
setTimeout(e, 1e3 / 60)
}, i(
".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"
), n(), r()
}(window, document);
</script>
</body>
</html>
index.html
index.html