Lekcja matmy - dodawanie 1
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const body = document.body;
|
||||
const topic = body.dataset.topic;
|
||||
const currentLessonId = parseInt(body.dataset.lessonId, 10);
|
||||
|
||||
if (!topic) return;
|
||||
|
||||
// --- Pobieranie danych o lekcjach ---
|
||||
const response = await fetch('lekcje.json');
|
||||
const allTopics = await response.json();
|
||||
const topicData = allTopics[topic];
|
||||
const lessons = topicData.lessons;
|
||||
const totalLessons = lessons.length;
|
||||
|
||||
// --- Inicjalizacja Dropdown Menu ---
|
||||
const dropdownContent = document.querySelector('.dropdown-content');
|
||||
const dropdownButton = document.querySelector('.dropdown-button');
|
||||
|
||||
lessons.forEach(lesson => {
|
||||
const a = document.createElement('a');
|
||||
a.href = lesson.url;
|
||||
a.textContent = `Lekcja ${lesson.id}: ${lesson.title}`;
|
||||
if (lesson.id === currentLessonId) {
|
||||
a.classList.add('active');
|
||||
}
|
||||
dropdownContent.appendChild(a);
|
||||
});
|
||||
|
||||
dropdownButton.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
dropdownContent.classList.toggle('show');
|
||||
});
|
||||
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!e.target.matches('.dropdown-button')) {
|
||||
if (dropdownContent.classList.contains('show')) {
|
||||
dropdownContent.classList.remove('show');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// --- Zarządzanie postępem ---
|
||||
const progressKey = `progress_${topic}`;
|
||||
let progress = JSON.parse(localStorage.getItem(progressKey)) || [];
|
||||
|
||||
const progressBar = document.querySelector('.progress');
|
||||
const progressLabel = document.querySelector('.progress-label');
|
||||
|
||||
function updateProgress() {
|
||||
const completedCount = progress.length;
|
||||
const progressPercentage = (completedCount / totalLessons) * 100;
|
||||
|
||||
if (progressBar) progressBar.style.width = `${progressPercentage}%`;
|
||||
if (progressLabel) progressLabel.textContent = `Postęp: ${completedCount}/${totalLessons}`;
|
||||
}
|
||||
|
||||
// --- Interaktywne zadania ---
|
||||
const interactiveInputs = document.querySelectorAll('.interactive-input');
|
||||
interactiveInputs.forEach(input => {
|
||||
input.addEventListener('change', () => {
|
||||
const correctAnswer = input.dataset.answer;
|
||||
const feedbackSpan = input.nextElementSibling;
|
||||
if (input.value === correctAnswer) {
|
||||
feedbackSpan.textContent = '✅ Dobrze!';
|
||||
feedbackSpan.style.color = 'green';
|
||||
input.style.borderColor = 'green';
|
||||
|
||||
// Sprawdź, czy wszystkie zadania na stronie są rozwiązane
|
||||
const allCorrect = Array.from(document.querySelectorAll('.interactive-input')).every(i => i.style.borderColor === 'green');
|
||||
|
||||
// Zapisz postęp, jeśli wszystkie zadania są poprawne
|
||||
if (allCorrect && !progress.includes(currentLessonId)) {
|
||||
progress.push(currentLessonId);
|
||||
localStorage.setItem(progressKey, JSON.stringify(progress));
|
||||
updateProgress();
|
||||
}
|
||||
} else {
|
||||
feedbackSpan.textContent = '❌ Spróbuj jeszcze raz.';
|
||||
feedbackSpan.style.color = 'red';
|
||||
input.style.borderColor = 'red';
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// --- Ćwiczenie "Start i doskocz" ---
|
||||
const jumpExercise = document.querySelector('#exercise2');
|
||||
if (jumpExercise) {
|
||||
const jumpButtons = jumpExercise.querySelectorAll('.jump-btn');
|
||||
const jumpFeedback = jumpExercise.querySelector('.jump-feedback');
|
||||
let jumpCounter = 5;
|
||||
let jumpsMade = 0;
|
||||
|
||||
jumpButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
if (button.classList.contains('activated')) return;
|
||||
|
||||
jumpsMade++;
|
||||
jumpCounter++;
|
||||
button.classList.add('activated');
|
||||
button.textContent = jumpCounter;
|
||||
|
||||
let feedbackText = "Start: 5";
|
||||
for (let i = 1; i <= jumpsMade; i++) {
|
||||
feedbackText += ` ↷ ${5 + i}`;
|
||||
}
|
||||
jumpFeedback.textContent = feedbackText;
|
||||
|
||||
// Po ostatnim skoku, wypełnij pole odpowiedzi
|
||||
if (jumpsMade === jumpButtons.length) {
|
||||
const targetInput = jumpExercise.querySelector('.interactive-input');
|
||||
targetInput.value = jumpCounter;
|
||||
// Wywołaj zdarzenie 'change', aby sprawdzić odpowiedź i zapisać postęp
|
||||
targetInput.dispatchEvent(new Event('change'));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// --- Losowe ćwiczenie "Start i doskocz" ---
|
||||
const randomExerciseContainer = document.getElementById('random-exercise-container');
|
||||
const retryButton = document.getElementById('retry-random-exercise');
|
||||
|
||||
function generateRandomExercise() {
|
||||
const num1 = Math.floor(Math.random() * 8) + 2; // 2-9
|
||||
const num2 = Math.floor(Math.random() * 8) + 2; // 2-9
|
||||
const startNum = Math.max(num1, num2);
|
||||
const jumpCount = Math.min(num1, num2);
|
||||
const answer = startNum + jumpCount;
|
||||
|
||||
let jumpsHTML = '';
|
||||
for (let i = 0; i < jumpCount; i++) {
|
||||
jumpsHTML += `<button class="jump-btn" data-value="${startNum + i + 1}">+1</button>`;
|
||||
}
|
||||
|
||||
randomExerciseContainer.innerHTML = `
|
||||
<div class="interactive-exercise" id="random-exercise">
|
||||
<h4>Ćwiczenie losowe</h4>
|
||||
<p>Mamy <strong>${startNum}</strong>. Chcemy dołożyć <strong>${jumpCount}</strong>.</p>
|
||||
<div class="start-and-jump">
|
||||
<div class="start-number">${startNum}</div>
|
||||
<div class="jumps">${jumpsHTML}</div>
|
||||
</div>
|
||||
<p>Klikaj przyciski "+1", żeby "doskoczyć" do wyniku. Jaki będzie wynik?</p>
|
||||
<div class="interactive-example">
|
||||
<span>${startNum} + ${jumpCount} = </span>
|
||||
<input type="number" class="interactive-input" data-answer="${answer}">
|
||||
<span class="feedback"></span>
|
||||
</div>
|
||||
<div class="jump-feedback">
|
||||
Start: ${startNum}...
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
setupRandomExerciseListeners();
|
||||
setupInteractiveInputs(); // Ponownie podłączamy listenery do nowo dodanych inputów
|
||||
}
|
||||
|
||||
function setupRandomExerciseListeners() {
|
||||
const exercise = document.getElementById('random-exercise');
|
||||
if (!exercise) return;
|
||||
|
||||
const jumpButtons = exercise.querySelectorAll('.jump-btn');
|
||||
const jumpFeedback = exercise.querySelector('.jump-feedback');
|
||||
const startNum = parseInt(exercise.querySelector('.start-number').textContent, 10);
|
||||
let jumpCounter = startNum;
|
||||
let jumpsMade = 0;
|
||||
|
||||
jumpButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
if (button.classList.contains('activated')) return;
|
||||
|
||||
jumpsMade++;
|
||||
jumpCounter++;
|
||||
button.classList.add('activated');
|
||||
button.textContent = jumpCounter;
|
||||
|
||||
let feedbackText = `Start: ${startNum}`;
|
||||
for (let i = 1; i <= jumpsMade; i++) {
|
||||
feedbackText += ` ↷ ${startNum + i}`;
|
||||
}
|
||||
jumpFeedback.textContent = feedbackText;
|
||||
|
||||
if (jumpsMade === jumpButtons.length) {
|
||||
const targetInput = exercise.querySelector('.interactive-input');
|
||||
targetInput.value = jumpCounter;
|
||||
targetInput.dispatchEvent(new Event('change'));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setupInteractiveInputs() {
|
||||
const allInputs = document.querySelectorAll('.interactive-input');
|
||||
allInputs.forEach(input => {
|
||||
// Usuń stare listenery, aby uniknąć duplikacji
|
||||
const newInput = input.cloneNode(true);
|
||||
input.parentNode.replaceChild(newInput, input);
|
||||
|
||||
newInput.addEventListener('change', () => {
|
||||
const correctAnswer = newInput.dataset.answer;
|
||||
const feedbackSpan = newInput.nextElementSibling;
|
||||
if (newInput.value === correctAnswer) {
|
||||
feedbackSpan.textContent = '✅ Dobrze!';
|
||||
feedbackSpan.style.color = 'green';
|
||||
newInput.style.borderColor = 'green';
|
||||
|
||||
const allCorrect = Array.from(document.querySelectorAll('.interactive-input')).every(i => i.style.borderColor === 'green');
|
||||
|
||||
if (allCorrect && !progress.includes(currentLessonId)) {
|
||||
progress.push(currentLessonId);
|
||||
localStorage.setItem(progressKey, JSON.stringify(progress));
|
||||
updateProgress();
|
||||
}
|
||||
} else {
|
||||
feedbackSpan.textContent = '❌ Spróbuj jeszcze raz.';
|
||||
feedbackSpan.style.color = 'red';
|
||||
newInput.style.borderColor = 'red';
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (randomExerciseContainer) {
|
||||
generateRandomExercise();
|
||||
retryButton.addEventListener('click', generateRandomExercise);
|
||||
} else {
|
||||
setupInteractiveInputs();
|
||||
}
|
||||
|
||||
|
||||
// Inicjalizacja paska postępu przy ładowaniu strony
|
||||
updateProgress();
|
||||
});
|
||||
Reference in New Issue
Block a user