Я хочу проверить, правильно ли нажимает кнопка, которую нажимает пользователь, тогда я что-то сделаю. Для этого я использую оператор if, чтобы проверить, соответствует ли значение кнопки «правильному» свойству в массиве «вопросы». До сих пор я пробовал эти решения, и ни одно из них не работает:
if (e.target.tagName === "BUTTON" && e.target.innerText === questions[i].correct) {
alert("correct"); /* testing */
}
if (e.target.tagName === "BUTTON" && e.target.textContent === questions[i].correct) {
alert("correct"); /* testing */
}
if (e.target.tagName === "BUTTON" && e.target.value === questions[i].correct) {
alert("correct"); /* testing */
}
if (e.target.tagName === "BUTTON" && e.target.innerHTML === questions[i].correct) {
alert("correct"); /* testing */
}
Вот html:
<!DOCTYPE html>
<html>
<head>
<title>Quiz Game</title>
<link rel = "stylesheet" type = "text/css" href = "quiz.css">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<link href = "https://fonts.googleapis.com/css?family=Roboto+Slab&display=swap" rel = "stylesheet">
</head>
<body>
<div id = "wrapper">
<p>Question <span class = "qtn-count">1</span> of 5</p>
<p>Score: 0</p>
<p id = "question"></p>
<div id = "btns-wrapper">
<button class = "btn"></button>
<button class = "btn"></button>
<button class = "btn"></button>
<button class = "btn"></button>
</div>
</div>
<button class = "btn" id = "start-btn">Start</button>
<script type = "text/javascript" src = "quiz.js"></script>
</body>
</html>
Вот CSS:
body {
font-family: 'Roboto Slab', serif;
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
padding: 0;
box-sizing: border-box;
background: #E987FF;
background: -moz-linear-gradient(left, #E987FF 0%, #B7DB81 50%, #FFEBEB 100%);
background: -webkit-linear-gradient(left, #E987FF 0%, #B7DB81 50%, #FFEBEB 100%);
background: linear-gradient(to right, #E987FF 0%, #B7DB81 50%, #FFEBEB 100%);
}
#question {
font-size: 20px;
flex-grow: 4;
text-align: center;
}
.btn {
background: rgb(240,248,255);
font-family: 'Roboto Slab', serif;
border: none;
border-radius: 5px;
outline: none;
text-shadow: 2px 2px 5px rgba(0,0,0,0.44);
cursor: pointer;
height: 50px;
width: 90%;
}
#btns-wrapper {
display: flex;
flex-direction: column;
margin: auto;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
width: 90%;
height: 50vh;
}
#wrapper {
-webkit-box-shadow: 4px 2px 17px 7px rgba(0,0,0,0.15);
box-shadow: 4px 2px 17px 7px rgba(0,0,0,0.15);
width: 90%;
font-family: 'Roboto Slab', serif;
background: #61FF68;
background: -moz-linear-gradient(left, #61FF68 0%, #4AC44F 50%, #6BFF98 100%);
background: -webkit-linear-gradient(left, #61FF68 0%, #4AC44F 50%, #6BFF98 100%);
background: linear-gradient(to right, #61FF68 0%, #4AC44F 50%, #6BFF98 100%);
display: none;
}
@media only screen and (min-width: 760px) {
#wrapper {
width: 50%;
}
#btns-wrapper {
display: flex;
flex-direction: row;
}
.btn {
width: 40%;
}
#question {
font-size: 30px;
}
}
И JavaScript:
const questions = [
{
question: "What is 2 + 2?",
answers: [3,4,2,5],
correct: 4
},
{
question: "What is 5 + 2?",
answers: [7,3,2,2],
correct: 7
},
{
question: "What is 10 + 20?",
answers: [35,40,24,30],
correct: 30
},
{
question: "What is 2 + 3?",
answers: [1,7,2,5],
correct: 5
}
]
const btn = document.getElementsByClassName("btn")
const btns_wrapper = document.getElementById("btns-wrapper");
const qtn = document.getElementById("question");
let i=0;
const start_btn = document.getElementById("start-btn");
const content = document.getElementById("wrapper");
start_btn.addEventListener("click" , ()=> {
content.style.display = "block";
start_btn.style.display = "none";
qtn.textContent = questions[i].question
btn[0].textContent = questions[0].answers[0];
btn[1].textContent = questions[0].answers[1];
btn[2].textContent = questions[0].answers[2];
btn[3].textContent = questions[0].answers[3];
i++;
});
btns_wrapper.addEventListener("click" , (e)=> {
if (e.target.tagName === "BUTTON" && e.target.innerText === questions[i].correct) {
alert("correct"); /* testing */
}
qtn.textContent = questions[i].question;
btn[0].textContent = questions[i].answers[0];
btn[1].textContent = questions[i].answers[1];
btn[2].textContent = questions[i].answers[2];
btn[3].textContent = questions[i].answers[3];
i++;
});
Также, когда я нажимаю кнопку после последнего вопроса, я получаю эту ошибку в консоли:
Uncaught TypeError: Cannot read property 'correct' of undefined
at HTMLDivElement.<anonymous> (quiz.js:69)
Я пробовал это, но это не сработало:
if (questions[i].question === undefined) {
/* do Something */
}
Спасибо за ваш отзыв. Обратите внимание, что я новичок в веб-разработке. Мой окончательный код будет выглядеть не так. Я просто проверяю, работает ли он, после чего я внесу некоторые изменения и реорганизую его в объектно-ориентированный стиль. «Просто запустите его на каждой кнопке». Вы имеете в виду прикрепить прослушиватель событий к каждой кнопке? Я прикрепил прослушиватель событий к btns_wrapper, потому что я хочу проверить правильность ответа, тогда я сделаю что-то вроде зеленого фона и одновременно перейду к следующему вопросу. Пожалуйста, сообщите мне, есть ли какие-либо другие предложения по улучшению моего кода.
У вас уже есть доступ к родителю без прослушивателя событий. Вам просто нужно добавить, удалить или включить класс btns_wrapper.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


1. i++ в вашем start_btn щелчке делает индекс вопросов неправильным после запуска.
2. i++ в вашем btns_wrapper клике должен быть до назначения текста в html.
3.e.target.innerText — это строка, а questions[i].correct — это число, поэтому сравнение должно быть e.target.innerText === questions[i].correct.toString() или e.target.innerText == questions[i].correct.
Рабочая версия:
const questions = [
{
question: "What is 2 + 2?",
answers: [3,4,2,5],
correct: 4
},
{
question: "What is 5 + 2?",
answers: [7,3,2,2],
correct: 7
},
{
question: "What is 10 + 20?",
answers: [35,40,24,30],
correct: 30
},
{
question: "What is 2 + 3?",
answers: [1,7,2,5],
correct: 5
}
]
const btn = document.getElementsByClassName("btn")
const btns_wrapper = document.getElementById("btns-wrapper");
const qtn = document.getElementById("question");
let i=0;
const start_btn = document.getElementById("start-btn");
const content = document.getElementById("wrapper");
start_btn.addEventListener("click" , ()=> {
content.style.display = "block";
start_btn.style.display = "none";
qtn.textContent = questions[i].question
btn[0].textContent = questions[i].answers[0];
btn[1].textContent = questions[i].answers[1];
btn[2].textContent = questions[i].answers[2];
btn[3].textContent = questions[i].answers[3];
});
btns_wrapper.addEventListener("click" , (e)=> {
if (e.target.tagName === "BUTTON" && e.target.innerText === questions[i].correct.toString()) {
alert("correct"); /* testing */
}
i++;
qtn.textContent = questions[i].question;
btn[0].textContent = questions[i].answers[0];
btn[1].textContent = questions[i].answers[1];
btn[2].textContent = questions[i].answers[2];
btn[3].textContent = questions[i].answers[3];
});body {
font-family: 'Roboto Slab', serif;
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
padding: 0;
box-sizing: border-box;
background: #E987FF;
background: -moz-linear-gradient(left, #E987FF 0%, #B7DB81 50%, #FFEBEB 100%);
background: -webkit-linear-gradient(left, #E987FF 0%, #B7DB81 50%, #FFEBEB 100%);
background: linear-gradient(to right, #E987FF 0%, #B7DB81 50%, #FFEBEB 100%);
}
#question {
font-size: 20px;
flex-grow: 4;
text-align: center;
}
.btn {
background: rgb(240,248,255);
font-family: 'Roboto Slab', serif;
border: none;
border-radius: 5px;
outline: none;
text-shadow: 2px 2px 5px rgba(0,0,0,0.44);
cursor: pointer;
height: 50px;
width: 90%;
}
#btns-wrapper {
display: flex;
flex-direction: column;
margin: auto;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
width: 90%;
height: 50vh;
}
#wrapper {
-webkit-box-shadow: 4px 2px 17px 7px rgba(0,0,0,0.15);
box-shadow: 4px 2px 17px 7px rgba(0,0,0,0.15);
width: 90%;
font-family: 'Roboto Slab', serif;
background: #61FF68;
background: -moz-linear-gradient(left, #61FF68 0%, #4AC44F 50%, #6BFF98 100%);
background: -webkit-linear-gradient(left, #61FF68 0%, #4AC44F 50%, #6BFF98 100%);
background: linear-gradient(to right, #61FF68 0%, #4AC44F 50%, #6BFF98 100%);
display: none;
}
@media only screen and (min-width: 760px) {
#wrapper {
width: 50%;
}
#btns-wrapper {
display: flex;
flex-direction: row;
}
.btn {
width: 40%;
}
#question {
font-size: 30px;
}<html>
<head>
<title>Quiz Game</title>
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<link href = "https://fonts.googleapis.com/css?family=Roboto+Slab&display=swap" rel = "stylesheet">
</head>
<body>
<div id = "wrapper">
<p>Question <span class = "qtn-count">1</span> of 5</p>
<p>Score: 0</p>
<p id = "question"></p>
<div id = "btns-wrapper">
<button class = "btn"></button>
<button class = "btn"></button>
<button class = "btn"></button>
<button class = "btn"></button>
</div>
</div>
<button class = "btn" id = "start-btn">Start</button>
</body>
</html>Спасибо. У вас есть решение для последней части моего вопроса?
вы можете просто проверить, если я >= вопросов.длина, а затем сделать что-то, чтобы справиться с этим, потому что, когда я >= вопросы.длина, questions[i] становится undefined. Это вызывает ошибку.
Еще раз спасибо, последний вопрос. Можете ли вы объяснить, как i++ в start_btn приводит к неправильному индексу вопроса?
сначала вы устанавливаете html для представления questions[0], а затем i++ делаете i равным 1. Поэтому, когда вы проверяете ответ, вы сравниваете questions[0] выбор с questions[1].correct
Плохой дизайн. Вы запускаете событие щелчка на оболочке кнопки? Зачем? Просто запустите его на каждой кнопке. Зачем проверять
e.target.tagName === "BUTTON" && e.target.innerText === questions[i].correct, когда у вас уже есть массив ответов, соответствующих кнопкам... другими словами, вы можете просто проверить индекс. Лично я бы использовал конструктор, чтобы вы могли очень легко создавать тесты каждой кнопки, каждый из которых был бы экземпляромnew.