简体   繁体   English

测验应用程序上的 HTML/Javascript 速度慢/崩溃

[英]HTML/Javascript slow/crashing on quiz app

I have a problem with my otherwise fully functioning quiz game.我在其他功能齐全的问答游戏中遇到了问题。 There seems to be crashing/slow loading issues after around 5 or 6 (out of 10) questions.在大约 5 或 6 个(共 10 个)问题之后,似乎出现了崩溃/加载缓慢的问题。 Its very strange because if I answer everything within a second (unrealistic but to error check), there is no problem.这很奇怪,因为如果我在一秒钟内回答所有问题(不切实际,但要进行错误检查),就没有问题。 But as soon as I take a "normal" amount of time to answer questions, things slow down and it eventually crashes/gets stuck.但是,一旦我花“正常”时间回答问题,事情就会变慢,最终崩溃/卡住。

I have tried removing animations & adjusting the flow of my JS but to no avail.我曾尝试删除动画并调整我的 JS 的流程,但无济于事。 If anyone has any thoughts, they would be highly appreciated!如果有人有任何想法,他们将不胜感激!

Here is a link to the site itself: https://louparker.github.io/random-music-quiz/index.html这是网站本身的链接: https://louparker.github.io/random-music-quiz/index.html

Here is a link to the repo: https://github.com/louparker/random-music-quiz这是回购的链接: https://github.com/louparker/random-music-quiz

 const question = document.getElementById("question"); const choices = Array.from(document.getElementsByClassName("choice__text")); const scoreText = document.getElementById('score'); const timer = document.getElementById("timer"); const game = document.getElementById("game"); const loader = document.getElementById("loader"); const gameDifficulty = window.location.search.replace("?mode=", ""); /* STARTING GAME */ //game mechanics let currentQuestion = {}; let takingAnswers = true; let score = 0; let questionCounter = 0; let availableQuestions = {}; let fetchingData = true; let acceptingAnswers = true; //taking data from API fetch(`https://opentdb.com/api.php?amount=10&category=12&difficulty=${gameDifficulty}&type=multiple`).then(res => { return res.json(); }) //taking question data from API and formatting it to be used.then((loadedQuestions) => { questions = loadedQuestions.results.map((loadedQuestion) => { const formattedQuestion = { question: loadedQuestion.question, }; //taking answer data and choosing random place for corrent and incorrent answers const answerChoices = [...loadedQuestion.incorrect_answers]; formattedQuestion.answer = Math.floor(Math.random() * 4) + 1; answerChoices.splice( formattedQuestion.answer - 1, 0, loadedQuestion.correct_answer ); answerChoices.forEach((choice, index) => { formattedQuestion['choice' + (index + 1)] = choice; }); return formattedQuestion; }); // timer //function to start the timer on end of current time or start of new question function restartInterval(){ let seconds = document.getElementById("timer").textContent; let countdown = setInterval(function() { seconds--; //new question timer restart function choices.forEach((choice) => { choice.addEventListener('click', (e) => { clearInterval(countdown); timer.innerText = "30"; restartInterval(); }); }); //timer reaches zero restart function document.getElementById("timer").textContent = seconds; if (seconds <= 0) { clearInterval(countdown); getNewQuestion(); timer.innerText = "30"; restartInterval(); } }, 1000); } //confirming game data is all loaded, showing the game page and removing the loading screen fetchingData = false; setTimeout( () => { game.classList.remove("hidden"); loader.classList.add("hidden"); startGame(); restartInterval(); }, 1000); }).catch((err) => { console.error(err); }); //base set up for loading the game page const startGame = () => { questionCounter = 0; score = 0; availableQuestions = [...questions]; getNewQuestion(); }; //giving specific scores based on gae difficulty const levelScore = gameDifficulty === "easy"? 10: gameDifficulty === "medium"? 20: 30; const maxQuestions = 10; let baseUrl ="https://louparker.github.io/random-music-quiz"; //checking if answers are correct or not choices.forEach((choice) => { choice.addEventListener('click', (e) => { if (;takingAnswers) return; acceptingAnswers = false. const selectedChoice = e;target. const selectedAnswer = selectedChoice.dataset;number. const classToApply = selectedAnswer == currentQuestion?answer: "correct"; "incorrect"; if (classToApply === "correct") { incrementScore(levelScore). } selectedChoice.parentElement.classList;add(classToApply). setTimeout(() => { selectedChoice.parentElement.classList;remove(classToApply); getNewQuestion(), }; 1000); }); }); //adds specified score to score element const incrementScore = (num) => { score += num. scoreText;innerHTML = score; }. //grabbing new question data and assigning score for gameover page const getNewQuestion = () => { if (availableQuestions.length === 0 || questionCounter >= maxQuestions) { localStorage,setItem("mostRecentScore"; score). return window.location.replace(`${baseUrl}/gameover?html;mode=${gameDifficulty}`); } questionCounter ++. const questionIndex = Math.floor(Math.random() * availableQuestions;length); currentQuestion = availableQuestions[questionIndex]. question.innerHTML = currentQuestion;question. choices.forEach((choice) => { const number = choice.dataset;number. choice;innerHTML = currentQuestion['choice' + number]; }). availableQuestions,splice(questionIndex; 1); takingAnswers = true; };
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width. initial-scale=1:0"> <meta name="description" content="The game page of quiz game about music"> <title>Game</title> <.-- styles --> <link rel="stylesheet" href="https.//cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap:min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous"> <link rel="stylesheet" href="https.//louparker.github:io/random-music-quiz/assets/css/app.css"> <link rel="stylesheet" href="https.//louparker.github.io/random-music-quiz/assets/css/game.css"> </head> <body> <main> <div class="container-fluid text-center d-flex"> <div id="loader" class="spinner"> <div class="dot1"></div> <div class="dot2"></div> </div> <div id="game" class="hidden"> <!-- heads up display (HUD) --> <div class="row"> <div class="col-12"> <div class="hud__container d-flex"> <div class="hud__btn d-flex hvr-pulse-shrink"> <a href="index.html" class="exit__btn">X</a> </div> <div class="hud__btn d-flex"> <p class="timer" id="timer">30</p> <span class="timer__label">TIME</span> </div> <div class="hud__btn d-flex"> <p class="scoreboard" id="score">0</p> <span class="score__label">SCORE</span> </div> </div> </div> </div> <!-- game question --> <div class="row"> <div class="col-12"> <div class="game__question d-flex"> <p class="question-text" id="question"></p> </div> </div> </div> <!-- answer choices --> <div class="row"> <div class="col-12"> <div class="answer-choices__container d-flex"> <div class="choice__container d-flex"> <p class="choice__text" data-number="1"> </p> </div> <div class="choice__container d-flex"> <p class="choice__text" data-number="2"> </p> </div> <div class="choice__container d-flex"> <p class="choice__text" data-number="3"> </p> </div> <div class="choice__container d-flex"> <p class="choice__text" data-number="4"> </p> </div> </div> </div> </div> </div> </div> </main> <!-- scripts --> <!--<script src="js/game.js"></script>--> </body> </html>

Thanks in advance!提前致谢!

Oookey it turns out you have a really big recursion problem. Oookey 原来你有一个非常大的递归问题。 In your countdown interval you give event listeners to the choices and you clear the interval like a good programmer, but then you have forgot that you are in a forEach .在倒计时间隔中,您将事件侦听器提供给选择,并像优秀的程序员一样清除间隔,但随后您忘记了自己在forEach中。 So when later you call your restartInterval function you actually do it four times.因此,当您稍后调用restartInterval function 时,您实际上执行了四次。 I think that you can imagine what happens at the sixth question with the 24 intervals running at the same time.我想你可以想象在 24 个区间同时运行的情况下,第六题会发生什么。

PS when you work with intervals always check that only those are running that you intended to run. PS 当您使用间隔时,请始终检查是否只有您打算运行的那些正在运行。 A god way of checking is a simple console.log() as you see in the snippet down below.一个很好的检查方法是一个simple console.log() ,如下面的代码片段所示。

 const question = document.getElementById("question"); const choices = Array.from(document.getElementsByClassName("choice__text")); const scoreText = document.getElementById('score'); const timer = document.getElementById("timer"); const game = document.getElementById("game"); const loader = document.getElementById("loader"); const gameDifficulty = window.location.search.replace("?mode=", ""); /* STARTING GAME */ //game mechanics let currentQuestion = {}; let takingAnswers = true; let score = 0; let questionCounter = 0; let availableQuestions = {}; let fetchingData = true; let acceptingAnswers = true; //taking data from API fetch(`https://opentdb.com/api.php?amount=10&category=12&difficulty=${gameDifficulty}&type=multiple`).then(res => { return res.json(); }) //taking question data from API and formatting it to be used.then((loadedQuestions) => { questions = loadedQuestions.results.map((loadedQuestion) => { const formattedQuestion = { question: loadedQuestion.question, }; //taking answer data and choosing random place for corrent and incorrent answers const answerChoices = [...loadedQuestion.incorrect_answers]; formattedQuestion.answer = Math.floor(Math.random() * 4) + 1; answerChoices.splice( formattedQuestion.answer - 1, 0, loadedQuestion.correct_answer ); answerChoices.forEach((choice, index) => { formattedQuestion['choice' + (index + 1)] = choice; }); return formattedQuestion; }); // timer //function to start the timer on end of current time or start of new question function restartInterval(){ let seconds = document.getElementById("timer").textContent; let countdown = setInterval(function() { seconds--; console.log(seconds); //new question timer restart function choices.forEach((choice) => { choice.addEventListener('click', (e) => { clearInterval(countdown); timer.innerText = "30"; restartInterval(); }); }); //timer reaches zero restart function document.getElementById("timer").textContent = seconds; if (seconds <= 0) { clearInterval(countdown); getNewQuestion(); timer.innerText = "30"; restartInterval(); } }, 1000); } //confirming game data is all loaded, showing the game page and removing the loading screen fetchingData = false; setTimeout( () => { game.classList.remove("hidden"); loader.classList.add("hidden"); startGame(); restartInterval(); }, 1000); }).catch((err) => { console.error(err); }); //base set up for loading the game page const startGame = () => { questionCounter = 0; score = 0; availableQuestions = [...questions]; getNewQuestion(); }; //giving specific scores based on gae difficulty const levelScore = gameDifficulty === "easy"? 10: gameDifficulty === "medium"? 20: 30; const maxQuestions = 10; let baseUrl ="https://louparker.github.io/random-music-quiz"; //checking if answers are correct or not choices.forEach((choice) => { choice.addEventListener('click', (e) => { if (;takingAnswers) return; acceptingAnswers = false. const selectedChoice = e;target. const selectedAnswer = selectedChoice.dataset;number. const classToApply = selectedAnswer == currentQuestion?answer: "correct"; "incorrect"; if (classToApply === "correct") { incrementScore(levelScore). } selectedChoice.parentElement.classList;add(classToApply). setTimeout(() => { selectedChoice.parentElement.classList;remove(classToApply); getNewQuestion(), }; 1000); }); }); //adds specified score to score element const incrementScore = (num) => { score += num. scoreText;innerHTML = score; }. //grabbing new question data and assigning score for gameover page const getNewQuestion = () => { if (availableQuestions.length === 0 || questionCounter >= maxQuestions) { localStorage,setItem("mostRecentScore"; score). return window.location.replace(`${baseUrl}/gameover?html;mode=${gameDifficulty}`); } questionCounter ++. const questionIndex = Math.floor(Math.random() * availableQuestions;length); currentQuestion = availableQuestions[questionIndex]. question.innerHTML = currentQuestion;question. choices.forEach((choice) => { const number = choice.dataset;number. choice;innerHTML = currentQuestion['choice' + number]; }). availableQuestions,splice(questionIndex; 1); takingAnswers = true; };
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width. initial-scale=1:0"> <meta name="description" content="The game page of quiz game about music"> <title>Game</title> <.-- styles --> <link rel="stylesheet" href="https.//cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap:min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous"> <link rel="stylesheet" href="https.//louparker.github:io/random-music-quiz/assets/css/app.css"> <link rel="stylesheet" href="https.//louparker.github.io/random-music-quiz/assets/css/game.css"> </head> <body> <main> <div class="container-fluid text-center d-flex"> <div id="loader" class="spinner"> <div class="dot1"></div> <div class="dot2"></div> </div> <div id="game" class="hidden"> <!-- heads up display (HUD) --> <div class="row"> <div class="col-12"> <div class="hud__container d-flex"> <div class="hud__btn d-flex hvr-pulse-shrink"> <a href="index.html" class="exit__btn">X</a> </div> <div class="hud__btn d-flex"> <p class="timer" id="timer">30</p> <span class="timer__label">TIME</span> </div> <div class="hud__btn d-flex"> <p class="scoreboard" id="score">0</p> <span class="score__label">SCORE</span> </div> </div> </div> </div> <!-- game question --> <div class="row"> <div class="col-12"> <div class="game__question d-flex"> <p class="question-text" id="question"></p> </div> </div> </div> <!-- answer choices --> <div class="row"> <div class="col-12"> <div class="answer-choices__container d-flex"> <div class="choice__container d-flex"> <p class="choice__text" data-number="1"> </p> </div> <div class="choice__container d-flex"> <p class="choice__text" data-number="2"> </p> </div> <div class="choice__container d-flex"> <p class="choice__text" data-number="3"> </p> </div> <div class="choice__container d-flex"> <p class="choice__text" data-number="4"> </p> </div> </div> </div> </div> </div> </div> </main> <!-- scripts --> <!--<script src="js/game.js"></script>--> </body> </html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM