190 lines
8.5 KiB
HTML
190 lines
8.5 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>Урок — Учитель китайского</title>
|
||
<style>
|
||
:root{--ink:#0F1218;--cyan:#00E5FF;--cyan-50:#E8FCFF;--white:#fff;--gray-500:#5B6573;--gray-100:#F2F4F7}
|
||
*{box-sizing:border-box;margin:0;padding:0}
|
||
body{font:17px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,sans-serif;color:var(--ink);background:var(--white)}
|
||
.container{max-width:800px;margin:0 auto;padding:40px 24px}
|
||
.header{background:var(--ink);color:var(--white)}
|
||
.header h1{font-size:36px;font-weight:800;margin-bottom:8px}
|
||
.header .sub{color:#9aa3b2;font-size:18px}
|
||
.nav{display:flex;justify-content:space-between;margin:32px 0;gap:12px}
|
||
.nav a{text-decoration:none;font-weight:700;padding:10px 20px;border-radius:8px;background:var(--gray-100);color:var(--ink)}
|
||
.nav a:hover{background:var(--cyan)}
|
||
.section{margin:48px 0}
|
||
.section h2{font-size:28px;font-weight:700;margin-bottom:20px;padding-bottom:8px;border-bottom:2px solid var(--cyan)}
|
||
.vocab-table{width:100%;border-collapse:collapse}
|
||
.vocab-table td{padding:10px 12px;border-bottom:1px solid var(--gray-100)}
|
||
.vocab-table .cn{font-size:22px;font-weight:700;width:25%}
|
||
.vocab-table .py{color:var(--gray-500);font-style:italic;width:30%}
|
||
.vocab-table .ru{width:45%}
|
||
.sentence{padding:16px 20px;background:var(--cyan-50);border-radius:12px;margin-bottom:12px}
|
||
.sentence .cn{font-size:20px;font-weight:700}
|
||
.sentence .py{color:var(--gray-500);font-style:italic;margin:4px 0}
|
||
.sentence .ru{color:var(--ink)}
|
||
.grammar{background:var(--gray-100);border-radius:16px;padding:24px;line-height:1.7}
|
||
.quiz{margin-top:32px}
|
||
.quiz h3{margin-bottom:16px}
|
||
.quiz-question{margin-bottom:20px}
|
||
.quiz-question p{font-weight:700;margin-bottom:8px}
|
||
.quiz-option{display:inline-block;margin:4px;padding:10px 20px;background:var(--gray-100);border-radius:8px;cursor:pointer;border:2px solid transparent;transition:.15s}
|
||
.quiz-option:hover{background:var(--cyan-50);border-color:var(--cyan)}
|
||
.quiz-option.selected{background:var(--cyan);border-color:var(--cyan)}
|
||
.quiz-option.correct{background:#d4edda;border-color:#28a745;color:#155724}
|
||
.quiz-option.wrong{background:#f8d7da;border-color:#dc3545;color:#721c24}
|
||
.quiz-option.disabled{pointer-events:none;opacity:.8}
|
||
.quiz-result{margin-top:16px;padding:16px;border-radius:12px;font-weight:700;display:none}
|
||
.quiz-result.pass{background:#d4edda;color:#155724;display:block}
|
||
.quiz-result.fail{background:#f8d7da;color:#721c24;display:block}
|
||
.back-btn{display:inline-block;margin-top:24px;padding:14px 28px;background:var(--cyan);color:var(--ink);border-radius:8px;font-weight:700;text-decoration:none}
|
||
.btn-check{display:inline-block;margin-top:16px;padding:12px 28px;background:var(--ink);color:var(--white);border:none;border-radius:8px;font-weight:700;cursor:pointer;font-size:16px;transition:.15s}
|
||
.btn-check:hover{opacity:.85}
|
||
.speaker{background:none;border:none;cursor:pointer;font-size:20px;padding:2px 6px;border-radius:6px;transition:.15s;vertical-align:middle;line-height:1}
|
||
.speaker:hover{background:var(--cyan-50)}
|
||
.vocab-table td{vertical-align:middle}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<section class="header">
|
||
<div class="container">
|
||
<h1 id="lesson-title">Загрузка...</h1>
|
||
<div class="sub" id="lesson-title-cn"></div>
|
||
</div>
|
||
</section>
|
||
<div class="container" id="lesson-content">
|
||
<div class="nav">
|
||
<a id="prev-link" href="#">← Предыдущий</a>
|
||
<a id="next-link" href="#">Следующий →</a>
|
||
</div>
|
||
|
||
<div class="section" id="vocab-section">
|
||
<h2>📖 Слова</h2>
|
||
<table class="vocab-table" id="vocab-table"></table>
|
||
</div>
|
||
|
||
<div class="section" id="sentences-section">
|
||
<h2>💬 Примеры</h2>
|
||
<div id="sentences-list"></div>
|
||
</div>
|
||
|
||
<div class="section" id="grammar-section">
|
||
<h2>📌 Грамматика</h2>
|
||
<div class="grammar" id="grammar-text"></div>
|
||
</div>
|
||
|
||
<div class="section quiz" id="quiz-section">
|
||
<h2>✏️ Проверь себя</h2>
|
||
<div id="quiz-list"></div>
|
||
<button class="btn-check" id="check-btn">Проверить</button>
|
||
<div class="quiz-result" id="quiz-result"></div>
|
||
</div>
|
||
|
||
<a class="back-btn" href="index.html">← На главную</a>
|
||
</div>
|
||
<script src="data.js"></script>
|
||
<script>
|
||
const url = new URL(window.location.href);
|
||
const id = parseInt(url.searchParams.get('id')) || 1;
|
||
const lesson = lessons.find(l => l.id === id);
|
||
|
||
if (!lesson) {
|
||
document.getElementById('lesson-title').textContent = 'Урок не найден';
|
||
document.getElementById('lesson-content').innerHTML = '<p>Такого урока нет. <a href="index.html">Вернуться на главную</a></p>';
|
||
} else {
|
||
document.title = `Урок ${lesson.id} — ${lesson.title} | Китайский с нуля`;
|
||
document.getElementById('lesson-title').textContent = `Урок ${lesson.id}: ${lesson.title}`;
|
||
document.getElementById('lesson-title-cn').textContent = lesson.titleCn;
|
||
|
||
let vocabHtml = '';
|
||
lesson.vocab.forEach(v => {
|
||
vocabHtml += `<tr><td class="cn">${v.cn} <button class="speaker" data-speak="${v.cn}">🔊</button></td><td class="py">${v.py}</td><td class="ru">${v.ru}</td></tr>`;
|
||
});
|
||
document.getElementById('vocab-table').innerHTML = vocabHtml;
|
||
|
||
let sentHtml = '';
|
||
lesson.sentences.forEach(s => {
|
||
sentHtml += `<div class="sentence"><div class="cn">${s.cn} <button class="speaker" data-speak="${s.cn}">🔊</button></div><div class="py">${s.py}</div><div class="ru">${s.ru}</div></div>`;
|
||
});
|
||
document.getElementById('sentences-list').innerHTML = sentHtml;
|
||
|
||
document.getElementById('lesson-content').addEventListener('click', function(e) {
|
||
const btn = e.target.closest('.speaker');
|
||
if (!btn) return;
|
||
const text = btn.dataset.speak;
|
||
const u = new SpeechSynthesisUtterance(text);
|
||
u.lang = 'zh-CN';
|
||
u.rate = 0.85;
|
||
speechSynthesis.cancel();
|
||
speechSynthesis.speak(u);
|
||
});
|
||
|
||
document.getElementById('grammar-text').textContent = lesson.grammar;
|
||
|
||
let quizHtml = '';
|
||
lesson.quiz.forEach((q, qi) => {
|
||
quizHtml += `<div class="quiz-question"><p>${qi + 1}. ${q.q}</p><div class="quiz-options" data-q="${qi}">`;
|
||
q.opts.forEach((opt, oi) => {
|
||
quizHtml += `<span class="quiz-option" data-qi="${qi}" data-oi="${oi}" data-val="${opt}">${opt}</span>`;
|
||
});
|
||
quizHtml += '</div></div>';
|
||
});
|
||
document.getElementById('quiz-list').innerHTML = quizHtml;
|
||
|
||
let selected = {};
|
||
document.querySelectorAll('.quiz-option').forEach(el => {
|
||
el.addEventListener('click', function() {
|
||
const qi = this.dataset.qi;
|
||
document.querySelectorAll(`.quiz-option[data-qi="${qi}"]`).forEach(o => o.classList.remove('selected'));
|
||
this.classList.add('selected');
|
||
selected[qi] = this.dataset.val;
|
||
});
|
||
});
|
||
|
||
document.getElementById('check-btn').addEventListener('click', function() {
|
||
let correct = 0;
|
||
lesson.quiz.forEach((q, qi) => {
|
||
document.querySelectorAll(`.quiz-option[data-qi="${qi}"]`).forEach(o => {
|
||
o.classList.remove('correct', 'wrong');
|
||
o.classList.add('disabled');
|
||
if (o.dataset.val === q.a) o.classList.add('correct');
|
||
else if (o.classList.contains('selected')) o.classList.add('wrong');
|
||
});
|
||
if (selected[qi] === q.a) correct++;
|
||
});
|
||
this.disabled = true;
|
||
this.style.opacity = '.5';
|
||
const total = lesson.quiz.length;
|
||
const result = document.getElementById('quiz-result');
|
||
if (correct === total) {
|
||
result.className = 'quiz-result pass';
|
||
result.textContent = `🎉 Отлично! ${correct}/${total} правильных! Урок пройден!`;
|
||
const done = JSON.parse(localStorage.getItem('chineseDone') || '[]');
|
||
if (!done.includes(lesson.id)) {
|
||
done.push(lesson.id);
|
||
localStorage.setItem('chineseDone', JSON.stringify(done));
|
||
}
|
||
} else {
|
||
result.className = 'quiz-result fail';
|
||
result.textContent = `✅ ${correct}/${total} правильных. Повтори слова и попробуй снова!`;
|
||
document.querySelectorAll('.quiz-option.disabled').forEach(o => o.classList.remove('disabled'));
|
||
this.disabled = false;
|
||
this.style.opacity = '1';
|
||
}
|
||
document.querySelectorAll('.quiz-option.selected').forEach(o => o.classList.remove('selected'));
|
||
});
|
||
|
||
const prev = document.getElementById('prev-link');
|
||
const next = document.getElementById('next-link');
|
||
if (id > 1) prev.href = `lesson.html?id=${id - 1}`;
|
||
else prev.style.display = 'none';
|
||
if (id < lessons.length) next.href = `lesson.html?id=${id + 1}`;
|
||
else next.style.display = 'none';
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|