'Why is my page not loading when clicking on event listener?
I'm creating an anime quiz. So when the user clicks on "Welcome to the anime quiz" s/he should be presented with 4 different anime titles. However, nothing happens when I do so. The page doesn't even load. The issue seems to come from the two lines of code I wrote in generateChoices(). When I comment them out and console.log("Hi") the code works. I don't know how to pin point the issue as when I uncomment the two lines of code in question I can't even use debugging. I think I might have created an infinite loop, but can't know for sure.
let japaneseAnime = [
{
name: "dragon ball",
picture: "https://dbgbh.bn-ent.net/assets/img/news/news_thumb_kv.png"
},
{
name: "Attack On Titans",
picture: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSJYjy_bS8t3ScWyG7q94fIltnar3ChaOHmGA&usqp=CAU"
},
{
name: "naruto",
picture: "https://res.cloudinary.com/jerrick/image/upload/v1616592065/605b3cc118e784001e22da0d.jpg"
},
{
name: "Demon Slayer",
picture: "https://cdn.vox-cdn.com/thumbor/gcVHhhZ4VwVswvbDPvI-RfQ7ECQ=/1400x1050/filters:format(png)/cdn.vox-cdn.com/uploads/chorus_asset/file/19721018/Tanjiro__Demon_Slayer_.png"
},
{
name: "Ghost in the shell",
picture: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS8VBbI5HMki5cmjP_Gq0TdyA6VZn_0_fmkhg&usqp=CAU"
}
]
const intro = document.querySelector(".intro");
const choices = [...document.querySelector(".question").children];
const anime = document.querySelector(".anime");
let anime_picture = document.querySelector(".anime_picture img");
let counter = [0]
intro.addEventListener("click", startQuiz);
function startQuiz() {
intro.classList.add("hide");
anime.classList.remove("hide");
generateChoices();
}
const getRandom = () => Math.floor(Math.random()*choices.length)
function uniqueChoices(count) {
let choicesArray = new Set()
while(!choicesArray.has(counter)) {
choicesArray.clear();
while(choicesArray.size < count) choicesArray.add(getRandom())
}
return [...choicesArray]
}
function generateChoices() {
let choicesArray = uniqueChoices(choices.length);
choices.forEach((choice, i) => choice.innerHTML = japaneseAnime[choicesArray[i]].name)
}
body {
position: relative;
display: flex;
justify-content: center;
align-content: center;
}
.intro {
height: 300px;
width: 300px;
border: 1px blue solid;
position: absolute;
left: 25%;
text-align: center;
}
.hide {
visibility: hidden;
}
.show {
visibility: visible;
}
.anime {
height: 800px;
width: 800px;
border: 1px red solid;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.anime_picture {
height: 400px;
width: 400px;
position: absolute;
}
.question {
height: 100px;
width: 100%;
border: 1px blue solid;
bottom: 0;
position: absolute;
display: flex;
justify-content: space-around;
align-items: center;
}
.question > div {
height: 80px;
width: auto;
border: 1px black solid;
background-color: #ddd;
}
img {
height: 100%;
width: 100%;
object-fit: cover;
}
header {
width: 100%;
height: 100px;
border: 1px black solid;
position: absolute;
top: 0;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="index.css">
<title>anime page</title>
</head>
<body>
<div class="intro">
welcome to the anime website
</div>
<div class="anime hide">
<div class="anime_picture">
<img src="" alt="">
</div>
<div class="question">
<div class="question1"></div>
<div class="question2"></div>
<div class="question3"></div>
<div class="question4"></div>
</div>
<header>anime Quiz</header>
</div>
</body>
<script src="index.js" type="text/javascript"></script>
</html>
Solution 1:[1]
Nested while statement at uniqueChoices
making an infinite Loop.
So,
- I made
getUniqueChoices
which returns a random element in japaneseAnime with the length of question list. Referencing code from how to make random elements form an array. - And replace
innerHTML
totextContent
. BecauseinnerHTML
is vulnerable to security issues.
const japaneseAnime = [
{
name: "dragon ball",
picture: "https://dbgbh.bn-ent.net/assets/img/news/news_thumb_kv.png"
},
{
name: "Attack On Titans",
picture:
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSJYjy_bS8t3ScWyG7q94fIltnar3ChaOHmGA&usqp=CAU"
},
{
name: "naruto",
picture:
"https://res.cloudinary.com/jerrick/image/upload/v1616592065/605b3cc118e784001e22da0d.jpg"
},
{
name: "Demon Slayer",
picture:
"https://cdn.vox-cdn.com/thumbor/gcVHhhZ4VwVswvbDPvI-RfQ7ECQ=/1400x1050/filters:format(png)/cdn.vox-cdn.com/uploads/chorus_asset/file/19721018/Tanjiro__Demon_Slayer_.png"
},
{
name: "Ghost in the shell",
picture:
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS8VBbI5HMki5cmjP_Gq0TdyA6VZn_0_fmkhg&usqp=CAU"
}
];
const intro = document.querySelector(".intro");
const anime = document.querySelector(".anime");
const anime_picture = document.querySelector(".anime_picture img");
const choices = [...document.querySelector(".question").children];
intro.addEventListener("click", startQuiz);
function startQuiz() {
intro.classList.add("hide");
anime.classList.remove("hide");
generateChoices();
}
function getUniqueChoices() {
return japaneseAnime.sort(() => 0.5 - Math.random()).slice(0, choices.length);
}
function generateChoices() {
const uniqueChoices = getUniqueChoices();
const randomNumber = Math.floor(Math.random() * choices.length);
anime_picture.src = uniqueChoices[randomNumber].picture;
choices.forEach((choice, i) => {
choice.textContent = uniqueChoices[i].name;
});
}
body {
position: relative;
display: flex;
justify-content: center;
align-content: center;
}
.intro {
height: 300px;
width: 300px;
border: 1px blue solid;
position: absolute;
left: 25%;
text-align: center;
cursor: pointer;
}
.hide {
visibility: hidden;
}
.show {
visibility: visible;
}
.anime {
height: 800px;
width: 800px;
border: 1px red solid;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.anime_picture {
height: 400px;
width: 400px;
position: absolute;
}
.question {
height: 100px;
width: 100%;
border: 1px blue solid;
bottom: 0;
position: absolute;
display: flex;
justify-content: space-around;
align-items: center;
}
.question > div {
height: 80px;
width: auto;
border: 1px black solid;
background-color: #ddd;
}
img {
height: 100%;
width: 100%;
object-fit: cover;
}
header {
width: 100%;
height: 100px;
border: 1px black solid;
position: absolute;
top: 0;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="index.css">
<title>anime page</title>
</head>
<body>
<div class="intro">
welcome to the anime website
</div>
<div class="anime hide">
<div class="anime_picture">
<img src="" alt="">
</div>
<div class="question">
<div class="question1"></div>
<div class="question2"></div>
<div class="question3"></div>
<div class="question4"></div>
</div>
<header>anime Quiz</header>
</div>
</body>
<script src="index.js" type="text/javascript"></script>
</html>
EDIT
I made it using Set
object that you need.
Hope this helps.
const japaneseAnime = [
{
name: "dragon ball",
picture: "https://dbgbh.bn-ent.net/assets/img/news/news_thumb_kv.png"
},
{
name: "Attack On Titans",
picture:
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSJYjy_bS8t3ScWyG7q94fIltnar3ChaOHmGA&usqp=CAU"
},
{
name: "naruto",
picture:
"https://res.cloudinary.com/jerrick/image/upload/v1616592065/605b3cc118e784001e22da0d.jpg"
},
{
name: "Demon Slayer",
picture:
"https://cdn.vox-cdn.com/thumbor/gcVHhhZ4VwVswvbDPvI-RfQ7ECQ=/1400x1050/filters:format(png)/cdn.vox-cdn.com/uploads/chorus_asset/file/19721018/Tanjiro__Demon_Slayer_.png"
},
{
name: "Ghost in the shell",
picture:
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS8VBbI5HMki5cmjP_Gq0TdyA6VZn_0_fmkhg&usqp=CAU"
}
];
const intro = document.querySelector(".intro");
const anime = document.querySelector(".anime");
const anime_picture = document.querySelector(".anime_picture img");
const choices = [...document.querySelector(".question").children];
const numOfChoices = [...document.querySelector(".question").children].length;
intro.addEventListener("click", startQuiz);
function startQuiz() {
intro.classList.add("hide");
anime.classList.remove("hide");
generateChoices();
}
function getRandomNumber () {
return Math.floor(Math.random() * numOfChoices)
}
function getUniqueChoices() {
const choicesArray = new Set()
while(choicesArray.size < numOfChoices) {
choicesArray.add(japaneseAnime[getRandomNumber()])
}
return [...choicesArray];
}
function generateChoices() {
const uniqueChoices = getUniqueChoices();
const randomNumber = getRandomNumber();
anime_picture.src = uniqueChoices[randomNumber].picture;
choices.forEach((choice, i) => {
choice.textContent = uniqueChoices[i].name;
});
}
body {
position: relative;
display: flex;
justify-content: center;
align-content: center;
}
.intro {
height: 300px;
width: 300px;
border: 1px blue solid;
position: absolute;
left: 25%;
text-align: center;
cursor: pointer;
}
.hide {
visibility: hidden;
}
.show {
visibility: visible;
}
.anime {
height: 800px;
width: 800px;
border: 1px red solid;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.anime_picture {
height: 400px;
width: 400px;
position: absolute;
}
.question {
height: 100px;
width: 100%;
border: 1px blue solid;
bottom: 0;
position: absolute;
display: flex;
justify-content: space-around;
align-items: center;
}
.question > div {
height: 80px;
width: auto;
border: 1px black solid;
background-color: #ddd;
}
img {
height: 100%;
width: 100%;
object-fit: cover;
}
header {
width: 100%;
height: 100px;
border: 1px black solid;
position: absolute;
top: 0;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="index.css">
<title>anime page</title>
</head>
<body>
<div class="intro">
welcome to the anime website
</div>
<div class="anime hide">
<div class="anime_picture">
<img src="" alt="">
</div>
<div class="question">
<div class="question1"></div>
<div class="question2"></div>
<div class="question3"></div>
<div class="question4"></div>
</div>
<header>anime Quiz</header>
</div>
</body>
<script src="index.js" type="text/javascript"></script>
</html>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |