Я пытаюсь разработать логику для викторины - Скрипка здесь . Я смотрел похожие проекты, такие как здесь и здесь. Однако их решения не подошли для моего теста; Я использую простой Javascript.
Путь вопроса развивает древовидную структуру. Например, первый вопрос спрашивает, какое вино вы любите? Если вы выберете красный, он спросит, предпочитаете ли вы игристое или негазированное. В конечном итоге ветви приводят к отображаемому результату.
Проблема в том, что я не могу даже перейти ко второму набору вопросов и вариантов выбора.
Может ли быть что-то не так с моей переменной объекта массива вопросов?
Мне удалось связать мои кнопки с первыми двумя метками (белой и красной) внутри функции beginQuiz, чтобы функция могла получить доступ к вершине дерева. Однако, если я попытаюсь получить доступ к более глубокому массиву, я получаю неопределенную ошибку.
например (функция showQuestion):
topBtn.innerHTML = questions[questionIndex].question.choices.label;
bottomBtn.innerHTML = questions[questionIndex].question.choices.label;
Область вопроса показывает неопределенность после того, как я нажму любую из кнопок выбора.
Я получаю эту ошибку:
Uncaught TypeError: невозможно прочитать свойства неопределенного (чтение «вопроса»)
Я могу получить первый вопрос и набор вариантов внутри функции beginQuiz, но не могу перейти к следующему набору. Что я делаю неправильно?
Как заставить его переходить к следующему набору вопросов и ярлыков и отображать их?
Заранее благодарю за любую помощь.
const questions = [
{
question: {
text: 'What type of wine do you like?',
choices: [
{
label: 'white',
path: 1,
question: {
text: 'I prefer...',
choices: [
{
label: 'sparkling',
path: 11,
},
{
label: 'still',
path: 12,
},
],
},
},
{
label: 'red',
path: 2,
question: {
text: 'I prefer...',
choices: [
{
label: 'sparkling',
path: 21,
},
{
label: 'still',
path: 22,
},
],
},
},
],
},
},
];
topBtn.addEventListener('click', nextQuestion);
bottomBtn.addEventListener('click', nextQuestion);
restartBtn.addEventListener('click', restart);
let questionIndex = 0;
function beginQuiz() {
let questionIndex = 0;
questionText.innerHTML = questions[questionIndex].question.text;
topBtn.innerHTML = questions[questionIndex].question.choices[0].label;
topBtn.addEventListener('click', () => {
if (questionIndex < 2) {
nextQuestion();
}
});
bottomBtn.innerHTML = questions[questionIndex].question.choices[1].label;
bottomBtn.addEventListener('click', () => {
if (questionIndex < 2) {
nextQuestion();
}
});
}
beginQuiz();
function showQuestion() {
questionText.innerHTML = questions[questionIndex];
topBtn.innerHTML = questions[questionIndex].question.choices.label;
bottomBtn.innerHTML = questions[questionIndex].question.choices.label;
}
function nextQuestion() {
questionIndex++;
showQuestion();
}
Спасибо за ваш комментарий, mykaf. Извините за задержку с ответом. Да, в случае с вопросами[currentQuestion].question.choices[0][1] я неправильно пытался проиндексировать то, чего не существовало. Теперь все исправлено. Спасибо.
В вашем коде, когда я жестко кодирую такой индекс с [0]:
questionText.innerHTML = questions[0].question.text;
topBtn.innerHTML = questions[0].question.choices[0].label;
Я действительно получаю первый вопрос и варианты/ответы.
Однако, когда я делаю это [1]:
questionText.innerHTML = questions[1].question.text;
topBtn.innerHTML = questions[1].question.choices[0].label;
Я получаю неопределенность!
Это говорит мне о том, что проблема заключается в том, как вы настраиваете свои структуры данных и как вы их выполняете. В индексе 1 ничего не найдено. Потому что у вас там ничего нет.
Также вы забыли добавить порядковые номера для меток, то есть ответов в строке 121 в jsfiddle.
questionText.innerHTML = questions[questionIndex].question.text;
topBtn.innerHTML =
questions[questionIndex].question.choices[0].label;
bottomBtn.innerHTML =
questions[questionIndex].question.choices[1].label;
Проверьте мой фрагмент кода ниже и, пожалуйста, проголосуйте, если решение работает для вас.
const restartBtn = document.getElementById('restart');
const topBtn = document.getElementById('top-btn');
const bottomBtn = document.getElementById('bottom-btn');
const questionText = document.querySelector('.question');
const choiceText = document.querySelector('.choices');
const resultText = document.querySelector('.result');
const questions = [
{
question: {
text: 'What type of wine do you like?',
choices: [
{
label: 'white',
path: 1,
question: {
text: 'I prefer...',
choices: [
{
label: 'sparkling',
path: 11,
},
{
label: 'still',
path: 12,
},
],
},
},
{
label: 'red',
path: 2,
question: {
text: 'I prefer...',
choices: [
{
label: 'sparkling',
path: 21,
},
{
label: 'still',
path: 22,
},
],
},
},
],
}, // index 0
},
{
question: {
text: 'Another more question?',
choices: [
{
label: 'this is my answer',
path: 1,
question: {
text: 'I prefer...',
choices: [
{
label: 'sparkling',
path: 11,
},
{
label: 'still',
path: 12,
},
],
},
},
{
label: 'another answer',
path: 2,
question: {
text: 'I prefer...',
choices: [
{
label: 'sparkling',
path: 21,
},
{
label: 'still',
path: 22,
},
],
},
},
],
}, // index 1
},
];
topBtn.addEventListener('click', nextQuestion);
bottomBtn.addEventListener('click', nextQuestion);
restartBtn.addEventListener('click', restart);
let questionIndex = 0;
function beginQuiz() {
let questionIndex = 0;
console.info(questionIndex, "index");
questionText.innerHTML = questions[questionIndex].question.text;
console.info(questions[questionIndex], "test");
topBtn.innerHTML = questions[questionIndex].question.choices[0].label;
topBtn.addEventListener('click', () => {
if (questionIndex < 3) {
nextQuestion();
}
});
bottomBtn.innerHTML = questions[questionIndex].question.choices[1].label;
bottomBtn.addEventListener('click', () => {
if (questionIndex < 3) {
nextQuestion();
}
});
}
beginQuiz();
function showQuestion() {
questionText.innerHTML = questions[questionIndex].question.text;
topBtn.innerHTML = questions[questionIndex].question.choices[0].label;
bottomBtn.innerHTML = questions[questionIndex].question.choices[1].label;
console.info( questions[questionIndex].question.choices[0].label, " questionText.innerHTML");
}
function nextQuestion() {
questionIndex++;
showQuestion();
}
function restart() {
questionIndex = 0;
currentQuestion = 0;
document.getElementById('question').style.display = 'block';
document.getElementById('choices').style.display = 'block';
document.getElementById('result').style.display = 'none';
topBtn.classList.remove('hide');
bottomBtn.classList.remove('hide');
beginQuiz();
}
function findProp(obj, prop) {
let result = [];
function recursivelyFindProp(o, keyToBeFound) {
Object.keys(o).forEach(function (key) {
if (typeof o[key] === 'object') {
recursivelyFindProp(o[key], keyToBeFound);
} else {
if (key === keyToBeFound) result.push(o[key]);
}
});
}
recursivelyFindProp(obj, prop);
return result;
}
console.info(findProp(questions, 'label'));
console.info(findProp(questions, 'text'));
console.info(findProp(questions, 'path'));
body {
background-color: darkkhaki;
font-family: serif;
}
h1 {
color: white;
text-align: center;
}
.container {
background-color: darkgoldenrod;
position: relative;
display: grid;
justify-content: center;
align-items: center;
text-align: center;
color: #fafafa;
padding: 20px;
border: 2px solid #fff;
border-radius: 20px;
}
.question {
font-size: 2em;
width: 90%;
height: auto;
margin: auto;
border-radius: 6px;
text-align: center;
}
.choices {
font-family: Courier, serif;
color: white;
margin-top: 2em;
}
.choice {
cursor: pointer;
font-size: 2em;
text-align: center;
}
.btn {
background-color: transparent;
color: #fff;
font-size: 12px;
text-transform: uppercase;
border: 3px solid #fff;
border-radius: 10px;
padding: 10px 20px;
margin: 10px;
cursor: pointer;
outline: none;
transition: all 0.5s ease;
}
.btn:hover {
background-color: #fff;
color: darkgoldenrod;
}
<body>
<header><h1>Wine chooser</h1></header>
<!--Quiz Box -->
<div class = "container">
<div class = "question" id = "question"></div>
<div class = "choices" id = "choices"></div>
<button class = "btn" id = "top-btn"></button>
<button class = "btn" id = "bottom-btn"></button>
<div class = "result" id = "result"></div>
</div>
<div class = "controls">
<button class = "btn btn-restart" id = "restart">Restart</button>
</div>
<script src = "test3.js"></script>
</body>
Привет, извините за поздний ответ. Большое спасибо, что нашли время, чтобы помочь с этим. Я понимаю, что вы имеете в виду по поводу проблемы с индексацией. В конце концов я упростил структуру вопросов, и это сработало.
Вы отладили, что такое
questions[currentQuestion].question.choices[0][1]
? Невозможно прочитать этикетку, если она не существует. Первое, что я вижу, это то, чтоchoices
— это массив, но вы рассматриваете его как двумерный массив.choices[0]
— это объект со строковыми ключами, поэтому индекс [1] отсутствует.