Lashtw commited on
Commit
22397d6
·
verified ·
1 Parent(s): c4ac625

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +141 -35
index.html CHANGED
@@ -351,6 +351,18 @@
351
  </div>
352
  </div>
353
 
 
 
 
 
 
 
 
 
 
 
 
 
354
  <footer class="fixed bottom-4 right-4 text-xs text-gray-500 text-right z-50">
355
  <p>遊戲設計者:新竹縣精華國中藍星宇</p>
356
  <p>FB教育社群:<a href="https://www.facebook.com/groups/1554372228718393" target="_blank" rel="noopener noreferrer" class="text-blue-500 hover:underline">萬物皆數</a></p>
@@ -444,6 +456,11 @@
444
  const confirmClearModal = document.getElementById('confirm-clear-modal');
445
  const cancelClearBtn = document.getElementById('cancel-clear-btn');
446
  const confirmClearBtn = document.getElementById('confirm-clear-btn');
 
 
 
 
 
447
 
448
  // 應用程式狀態
449
  let words = [];
@@ -455,6 +472,7 @@
455
  let completionStatus = {};
456
  let bookTitle = '';
457
  let lessonTitle = '';
 
458
  const MANAGE_PASSWORD = 'Ghjh';
459
  let highScore = 0;
460
  let currentScore = 0;
@@ -528,13 +546,9 @@
528
  editChineseInput.value = words[index].chinese;
529
  editWordModal.classList.remove('hidden');
530
  } else if (button.classList.contains('delete-btn')) {
531
- const itemElement = button.closest('.list-item');
532
- itemElement.classList.add('removing');
533
- setTimeout(() => {
534
- words.splice(index, 1);
535
- saveWordsToStorage();
536
- renderWordList();
537
- }, 300);
538
  }
539
  });
540
 
@@ -680,7 +694,7 @@
680
 
681
  quizContainer.classList.remove('hidden');
682
  reviewNavContainer.classList.toggle('hidden', !isReview);
683
- progressBarContainer.classList.toggle('hidden', !isQuiz);
684
  speedHud.classList.toggle('hidden', !isSpeed);
685
  hudPlaceholder.classList.toggle('hidden', isSpeed);
686
 
@@ -721,54 +735,113 @@
721
  };
722
 
723
  const checkAnswer = () => {
724
- const userAnswer = answerInput.value.trim();
725
- if (!userAnswer) return;
726
- if (currentMode === 'speed' && timeLeft <= 0) return;
727
  const isSpeed = currentMode === 'speed';
728
- const card = isSpeed ? currentSpeedCard : quizQueue[0];
 
 
 
 
729
  if (!card) return;
 
730
  const wordIndex = words.findIndex(w => w.english === card.english && w.chinese === card.chinese);
 
731
  let correctAnswer;
732
- const questionType = isSpeed ? currentSpeedQuestionType : (currentMode === 'hard' ? 'zh-en' : currentMode);
733
- switch (questionType) {
734
- case 'zh-en': case 'listen': correctAnswer = card.english.split('(')[0].trim(); break;
735
- case 'en-zh': correctAnswer = card.chinese.split('(')[0].trim(); break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
736
  }
737
- const isCorrect = userAnswer.toLowerCase() === correctAnswer.toLowerCase();
738
 
739
  if (isCorrect) {
740
- answerInput.disabled = true; submitBtn.disabled = true;
741
- feedbackDisplay.textContent = '答對了!'; feedbackDisplay.classList.remove('text-red-500'); feedbackDisplay.classList.add('text-green-600');
742
- triggerConfetti(); flashcardContainer.classList.add('flipped');
743
- if (!isSpeed && wordIndex !== -1) words[wordIndex].proficiency = (words[wordIndex].proficiency || 0) + 1;
 
 
 
 
 
 
744
  if (isSpeed) {
745
- currentScore++; scoreDisplay.textContent = `得分: ${currentScore}`;
 
746
  setTimeout(startSpeedCard, 500);
747
  } else {
748
- quizQueue.shift();
 
749
  setTimeout(() => {
750
- if (quizQueue.length > 0) displayCard();
751
- else {
 
 
 
 
 
 
 
 
752
  feedbackDisplay.textContent = '恭喜你,全部完成了!';
753
  if (currentMode !== 'hard') {
754
- completionStatus[currentMode] = true; localStorage.setItem('completionStatus', JSON.stringify(completionStatus)); updateCompletionUI();
 
 
755
  }
756
- answerInput.disabled = true; submitBtn.disabled = true;
 
757
  }
758
  }, 1500);
759
  }
760
- } else {
761
- quizIncorrectCount++; updateHintButtonVisibility();
 
762
  answerInput.classList.add('shake');
763
- if (!isSpeed && wordIndex !== -1) {
764
- words[wordIndex].proficiency = 0; words[wordIndex].incorrectCount = (words[wordIndex].incorrectCount || 0) + 1;
 
 
765
  }
 
766
  if (isSpeed) {
767
- feedbackDisplay.textContent = '答錯了,再試一次!'; feedbackDisplay.classList.add('text-red-500');
 
768
  setTimeout(() => { answerInput.classList.remove('shake'); feedbackDisplay.textContent = ''; }, 1000);
769
- } else {
770
- answerInput.disabled = true; submitBtn.disabled = true;
771
- flashcardContainer.classList.add('flipped'); quizContainer.classList.add('hidden');
 
 
 
 
 
 
 
772
  wrongAnswerFeedback.classList.remove('hidden');
773
  setTimeout(() => { answerInput.classList.remove('shake'); }, 820);
774
  }
@@ -776,6 +849,7 @@
776
  if (!isSpeed) saveWordsToStorage();
777
  };
778
 
 
779
  const updateHintButtonVisibility = () => {
780
  const isQuiz = currentMode !== 'review' && currentMode !== 'speed';
781
  const shouldShow = isQuiz && quizIncorrectCount >= 2;
@@ -994,6 +1068,38 @@
994
  confirmClearModal.classList.add('hidden');
995
  });
996
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
997
  // --- 應用程式初始化 ---
998
  const initializeApp = () => {
999
  const urlParams = new URLSearchParams(window.location.search);
 
351
  </div>
352
  </div>
353
 
354
+ <!-- 單字刪除確認 Modal -->
355
+ <div id="confirm-delete-modal" class="hidden fixed inset-0 bg-gray-900 bg-opacity-75 flex items-center justify-center z-50 p-4">
356
+ <div class="bg-white p-8 rounded-2xl shadow-xl w-full max-w-sm">
357
+ <h3 class="text-2xl font-bold mb-4 text-gray-800">確認刪除</h3>
358
+ <p class="text-gray-600 mb-6">您確定要刪除單字 "<span id="word-to-delete" class="font-bold"></span>" 嗎?此操作無法復原。</p>
359
+ <div class="flex justify-end gap-4 mt-6">
360
+ <button type="button" id="cancel-delete-btn" class="px-6 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 transition-colors">取消</button>
361
+ <button type="button" id="confirm-delete-btn" class="px-6 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors">確認刪除</button>
362
+ </div>
363
+ </div>
364
+ </div>
365
+
366
  <footer class="fixed bottom-4 right-4 text-xs text-gray-500 text-right z-50">
367
  <p>遊戲設計者:新竹縣精華國中藍星宇</p>
368
  <p>FB教育社群:<a href="https://www.facebook.com/groups/1554372228718393" target="_blank" rel="noopener noreferrer" class="text-blue-500 hover:underline">萬物皆數</a></p>
 
456
  const confirmClearModal = document.getElementById('confirm-clear-modal');
457
  const cancelClearBtn = document.getElementById('cancel-clear-btn');
458
  const confirmClearBtn = document.getElementById('confirm-clear-btn');
459
+ const confirmDeleteModal = document.getElementById('confirm-delete-modal');
460
+ const wordToDeleteSpan = document.getElementById('word-to-delete');
461
+ const cancelDeleteBtn = document.getElementById('cancel-delete-btn');
462
+ const confirmDeleteBtn = document.getElementById('confirm-delete-btn');
463
+
464
 
465
  // 應用程式狀態
466
  let words = [];
 
472
  let completionStatus = {};
473
  let bookTitle = '';
474
  let lessonTitle = '';
475
+ let indexToDelete = -1;
476
  const MANAGE_PASSWORD = 'Ghjh';
477
  let highScore = 0;
478
  let currentScore = 0;
 
546
  editChineseInput.value = words[index].chinese;
547
  editWordModal.classList.remove('hidden');
548
  } else if (button.classList.contains('delete-btn')) {
549
+ indexToDelete = index;
550
+ wordToDeleteSpan.textContent = words[index].english;
551
+ confirmDeleteModal.classList.remove('hidden');
 
 
 
 
552
  }
553
  });
554
 
 
694
 
695
  quizContainer.classList.remove('hidden');
696
  reviewNavContainer.classList.toggle('hidden', !isReview);
697
+ progressBarContainer.classList.toggle('hidden', isReview || isSpeed);
698
  speedHud.classList.toggle('hidden', !isSpeed);
699
  hudPlaceholder.classList.toggle('hidden', isSpeed);
700
 
 
735
  };
736
 
737
  const checkAnswer = () => {
738
+ const userAnswer = answerInput.value.trim();
739
+ if (!userAnswer) return;
740
+
741
  const isSpeed = currentMode === 'speed';
742
+ const isReview = currentMode === 'review';
743
+
744
+ if (isSpeed && timeLeft <= 0) return;
745
+
746
+ const card = isReview ? wordsForCurrentMode[currentCardIndex] : (isSpeed ? currentSpeedCard : quizQueue[0]);
747
  if (!card) return;
748
+
749
  const wordIndex = words.findIndex(w => w.english === card.english && w.chinese === card.chinese);
750
+
751
  let correctAnswer;
752
+ let answerLang;
753
+ let effectiveMode = currentMode;
754
+ if (isSpeed) effectiveMode = currentSpeedQuestionType;
755
+ if (currentMode === 'hard') effectiveMode = 'zh-en';
756
+
757
+ switch (effectiveMode) {
758
+ case 'zh-en':
759
+ case 'listen':
760
+ correctAnswer = card.english.split('(')[0].trim();
761
+ answerLang = 'en';
762
+ break;
763
+ case 'en-zh':
764
+ case 'review':
765
+ correctAnswer = card.chinese.split('(')[0].trim();
766
+ answerLang = 'zh';
767
+ break;
768
+ }
769
+
770
+ let isCorrect;
771
+ if (answerLang === 'en') {
772
+ const normalize = (str) => str.toLowerCase().replace(/[.,/#!$%^&*;:{}=\-_`~()]/g, "").trim();
773
+ isCorrect = normalize(userAnswer) === normalize(correctAnswer);
774
+ } else if (answerLang === 'zh') {
775
+ const possibleAnswers = correctAnswer.split(/[;;]/).map(a => a.trim());
776
+ isCorrect = possibleAnswers.some(ans => userAnswer.trim().includes(ans) && ans !== '');
777
+ } else {
778
+ isCorrect = userAnswer.trim().toLowerCase() === correctAnswer.trim().toLowerCase();
779
  }
 
780
 
781
  if (isCorrect) {
782
+ answerInput.disabled = true;
783
+ submitBtn.disabled = true;
784
+ feedbackDisplay.textContent = '答對了!';
785
+ feedbackDisplay.classList.remove('text-red-500');
786
+ feedbackDisplay.classList.add('text-green-600');
787
+ triggerConfetti();
788
+ flashcardContainer.classList.add('flipped');
789
+
790
+ if (wordIndex !== -1) words[wordIndex].proficiency = (words[wordIndex].proficiency || 0) + 1;
791
+
792
  if (isSpeed) {
793
+ currentScore++;
794
+ scoreDisplay.textContent = `得分: ${currentScore}`;
795
  setTimeout(startSpeedCard, 500);
796
  } else {
797
+ if (!isReview) quizQueue.shift();
798
+
799
  setTimeout(() => {
800
+ if (isReview) {
801
+ if (currentCardIndex < wordsForCurrentMode.length - 1) {
802
+ currentCardIndex++;
803
+ displayCard();
804
+ } else {
805
+ feedbackDisplay.textContent = '恭喜你,全部複習完了!';
806
+ }
807
+ } else if (quizQueue.length > 0) {
808
+ displayCard();
809
+ } else {
810
  feedbackDisplay.textContent = '恭喜你,全部完成了!';
811
  if (currentMode !== 'hard') {
812
+ completionStatus[currentMode] = true;
813
+ localStorage.setItem('completionStatus', JSON.stringify(completionStatus));
814
+ updateCompletionUI();
815
  }
816
+ answerInput.disabled = true;
817
+ submitBtn.disabled = true;
818
  }
819
  }, 1500);
820
  }
821
+ } else { // Incorrect answer
822
+ quizIncorrectCount++;
823
+ updateHintButtonVisibility();
824
  answerInput.classList.add('shake');
825
+
826
+ if (wordIndex !== -1) {
827
+ words[wordIndex].proficiency = 0;
828
+ words[wordIndex].incorrectCount = (words[wordIndex].incorrectCount || 0) + 1;
829
  }
830
+
831
  if (isSpeed) {
832
+ feedbackDisplay.textContent = '答錯了,再試一次!';
833
+ feedbackDisplay.classList.add('text-red-500');
834
  setTimeout(() => { answerInput.classList.remove('shake'); feedbackDisplay.textContent = ''; }, 1000);
835
+ } else if (isReview) {
836
+ feedbackDisplay.textContent = '答錯了!';
837
+ feedbackDisplay.classList.add('text-red-500');
838
+ flashcardContainer.classList.add('flipped');
839
+ setTimeout(() => { answerInput.classList.remove('shake'); }, 820);
840
+ } else { // Other quiz modes
841
+ answerInput.disabled = true;
842
+ submitBtn.disabled = true;
843
+ flashcardContainer.classList.add('flipped');
844
+ quizContainer.classList.add('hidden');
845
  wrongAnswerFeedback.classList.remove('hidden');
846
  setTimeout(() => { answerInput.classList.remove('shake'); }, 820);
847
  }
 
849
  if (!isSpeed) saveWordsToStorage();
850
  };
851
 
852
+
853
  const updateHintButtonVisibility = () => {
854
  const isQuiz = currentMode !== 'review' && currentMode !== 'speed';
855
  const shouldShow = isQuiz && quizIncorrectCount >= 2;
 
1068
  confirmClearModal.classList.add('hidden');
1069
  });
1070
 
1071
+ cancelDeleteBtn.addEventListener('click', () => {
1072
+ confirmDeleteModal.classList.add('hidden');
1073
+ indexToDelete = -1;
1074
+ });
1075
+
1076
+ confirmDeleteBtn.addEventListener('click', () => {
1077
+ if (indexToDelete > -1) {
1078
+ const allDeleteButtons = wordListContainer.querySelectorAll('.delete-btn');
1079
+ let itemElement = null;
1080
+ allDeleteButtons.forEach(btn => {
1081
+ if(parseInt(btn.dataset.index, 10) === indexToDelete) {
1082
+ itemElement = btn.closest('.list-item');
1083
+ }
1084
+ });
1085
+
1086
+ if (itemElement) {
1087
+ itemElement.classList.add('removing');
1088
+ }
1089
+
1090
+ setTimeout(() => {
1091
+ if (indexToDelete > -1) {
1092
+ words.splice(indexToDelete, 1);
1093
+ saveWordsToStorage();
1094
+ renderWordList();
1095
+ }
1096
+ }, 300);
1097
+ }
1098
+ confirmDeleteModal.classList.add('hidden');
1099
+ indexToDelete = -1;
1100
+ });
1101
+
1102
+
1103
  // --- 應用程式初始化 ---
1104
  const initializeApp = () => {
1105
  const urlParams = new URLSearchParams(window.location.search);