#javascript #html
#javascript #HTML
Вопрос:
Я разрабатываю простое приложение для викторины с использованием ванильного JavaScript и HTML. Функциональность, позволяющая узнать, правильный или неправильный выбранный ответ, и отобразить некоторую обратную связь, работает, но не функциональность для установки .quiz__marker
атрибута данных div на «Правильный» или «Неправильный» при выборе переключателя вопроса. Мой упрощенный код включен в приведенный ниже фрагмент.
Я установил .quiz__marker
для divs значение зеленого или красного цвета в зависимости от того, выбран правильный или неправильный ответ. Как вы можете видеть, все кружки становятся зелеными или красными при выборе переключателя.
Как я должен настроить свой JS-код, чтобы применять изменение цвета только к одному кругу? Кроме того, что мне нужно реализовать, чтобы цвет сохранялся на протяжении всего теста?
Я изучаю JavaScript по ходу дела. Предпочтительнее использовать ванильные ответы на JS.
Приветствия!
Обновление — включено полное quiz.js для целей проверки
function answerTracker() {
const tracker = document.querySelector(".quiz__tracker");
// Each quiz contains eight or less questions
const questions = 8;
for (let i = 1; i <= questions; i ) {
let trackerMarker = document.createElement("div");
trackerMarker.className = "quiz__marker";
trackerMarker.id = "marker_" i;
trackerMarker.setAttribute("data-answer", "");
tracker.appendChild(trackerMarker);
}
}
function questionMarkers() {
let labels = document.querySelectorAll("div[class*='rsform-block-question'] .formControlLabel");
let count = labels.length;
for (let i = 0; i < count; i ) {
let marker = `<span class="question-marker">${i 1}</span>`;
labels[i].insertAdjacentHTML("beforebegin", marker);
}
}
const runQuiz = (() => {
// Generate tracker
answerTracker();
// Append question markers to labels
questionMarkers();
// Set quiz score to zero
let score = 0;
let markers = document.querySelectorAll(".quiz__marker");
let answers = document.querySelectorAll(".rsform-radio");
answers.forEach(function (answer) {
answer.addEventListener("click", (e) => {
let target = e.target;
let container = target.closest(".formContainer");
let correct = container.querySelector("div[class$='true']");
let wrong = container.querySelector("div[class$='false']");
let feedback = container.querySelector("div[class$='feedback']");
let question = container.querySelector("div[class*='rsform-block-question']");
let next = container.querySelector(".js-btn--next.success");
let submit = container.querySelector(".js-btn--submit.rsform-submit-button");
if (e.target.value == "t") {
// If answer is correct, increment the user's score by one
score ;
correct.style.display = "block";
wrong.style.display = "none";
feedback.style.display = "block";
document.getElementById("marker_" e.target.dataset.num).setAttribute("data-answer", "Correct");
} else {
correct.style.display = "none";
wrong.style.display = "block";
feedback.style.display = "block";
document.getElementById("marker_" e.target.dataset.num).setAttribute("data-answer", "Incorrect");
}
if (next !== null amp;amp; next !== "") {
next.style.display = "block";
}
if (submit !== null amp;amp; submit !== "") {
submit.style.display = "block";
}
question.style.display = "none";
});
});
// If this is the final question in the quiz, assign the score variable to the final-score hidden HTML field
// document.getElementById("final-score").value = score;
})();
function answerTracker() {
const tracker = document.querySelector(".quiz__sidebar");
// Each quiz contains eight questions
const questions = 8;
for (let i = 1; i <= questions; i ) {
let trackerMarker = document.createElement("div");
trackerMarker.className = "quiz__marker";
trackerMarker.setAttribute("data-answer", "");
tracker.appendChild(trackerMarker);
}
}
const runQuiz = (() => {
// Generate answer tracker
answerTracker();
// Set quiz score to zero
let score = 0;
// Get node list of .quiz__marker DIVs
let markers = document.querySelectorAll(".quiz__marker");
// Get node list of answer radio buttons
let answers = document.querySelectorAll(".rsform-radio");
answers.forEach(function(answer) {
answer.addEventListener("click", (e) => {
let target = e.target;
let container = target.closest(".formContainer");
let correct = container.querySelector("div[class$='true']");
let wrong = container.querySelector("div[class$='false']");
let feedback = container.querySelector("div[class$='feedback']");
let question = container.querySelector("div[class*='rsform-block-question']");
let next = container.querySelector(".js-btn--next.success");
if (e.target.value == "t") {
// If answer is correct, increment the user's score by one
score ;
correct.style.display = "block";
wrong.style.display = "none";
feedback.style.display = "block";
} else {
correct.style.display = "none";
wrong.style.display = "block";
feedback.style.display = "block";
}
// Loop through node list and set data-attribute to "Correct" or "Incorrect" depending on e.target value
Array.from(markers).forEach(link => {
if (e.target.value == "t") {
link.setAttribute("data-answer", "Correct");
} else {
link.setAttribute("data-answer", "Incorrect");
}
});
// If question has been answered, display the next button
if (next !== null amp;amp; next !== "") {
next.style.display = "block";
}
});
});
// If this is the final question in the quiz, assign the score variable to the final-score hidden HTML field
// document.getElementById("final-score").value = score;
})();
.quiz__sidebar .quiz__marker {
display: inline-block;
width: 20px;
height: 20px;
margin: 6px;
background-color: grey;
border-radius: 50%;
}
.quiz__sidebar .quiz__marker[data-answer="Correct"] {
background-color: green;
}
.quiz__sidebar .quiz__marker[data-answer="Incorrect"] {
background-color: red;
}
form.quiz__form .formHidden,
form.quiz__form div[class$="true"],
form.quiz__form div[class$="false"],
form.quiz__form div[class$="feedback"],
form.quiz__form .rsform-block .rsform-button {
display: none;
}
<div class="quiz">
<div class="quiz__sidebar"></div>
<form class="quiz__form">
<div class="formContainer">
<div class="rsform-block-question-one">
<input type="radio" name="form[question-one]" value="f" id="question-one0" class="rsform-radio">
<label for="question-one0">To attract a mate</label>
<br>
<input type="radio" name="form[question-one]" value="t" id="question-one1" class="rsform-radio">
<label for="question-one1">To defend themselves against predators</label>
<br>
<input type="radio" name="form[question-one]" value="f" id="question-one2" class="rsform-radio">
<label for="question-one2">To mark their territory</label>
<br>
<input type="radio" name="form[question-one]" value="f" id="question-one3" class="rsform-radio">
<label for="question-one3">Because they like the smell</label>
</div>
<div class="rsform-block-question-one-true">
<p>
<strong>Correct!</strong>
</p>
</div>
<div class="rsform-block-question-one-false">
<p>
<strong>Nice try</strong>
</p>
</div>
<div class="rsform-block-question-one-feedback">
<p>Skunks spray an extremely offensive odour to make predators go away and leave them alone. If they feel their life is in danger, they have no other defence as they cannot run fast, climb, burrow under the ground, or fight.</p>
</div>
<div class="rsform-block">
<button type="button" class="btn--next js-btn--next rsform-button success button" style="display: none;">
Next
</button>
</div>
</div>
<div class="formContainer formHidden">
<div class="rsform-block-question-two">
<input type="radio" name="form[question-two]" value="f" id="question-two0" class="rsform-radio">
<label for="question-two0">1 cup</label>
<br>
<input type="radio" name="form[question-two]" value="f" id="question-two1" class="rsform-radio">
<label for="question-two1">Endless supply</label>
<br>
<input type="radio" name="form[question-two]" value="t" id="question-two2" class="rsform-radio">
<label for="question-two2">2 tbsp</label>
<br>
<input type="radio" name="form[question-two]" value="f" id="question-two3" class="rsform-radio">
<label for="question-two3">1 tsp</label>
</div>
<div class="rsform-block-question-two-true">
<p>
<strong>Correct!</strong>
</p>
</div>
<div class="rsform-block-question-two-false">
<p>
<strong>Nice try</strong>
</p>
</div>
<div class="rsform-block-question-two-feedback">
<p>Skunks have only 2 tbsp (30ml) of spray and it takes them more than a week to re-supply. They cannot spray every day as they will simply run out. Skunks use spraying as a last resort only as if they run out, they are defenceless against predators.</p>
</div>
<div class="rsform-block">
<button type="button" class="btn--next js-btn--next rsform-button success button" style="display: none;">
Next
</button>
</div>
</div>
</form>
</div>
Комментарии:
1. Я бы, конечно, создал CSS — классы, например. неправильно / .правильно; и применяйте эти атрибуты к каждому ответу, так что скажите, что они отвечают на B (будет сделана ссылка на элемент, и вы установите его неправильно / правильно.
2. Пожалуйста, проверьте ответ, который я опубликовал ниже
Ответ №1:
Вам нужно добавить некоторые характерные «маркеры» для маркеров викторины, например идентификатор с номером вопроса:
for (let i = 1; i <= questions; i ) {
let trackerMarker = document.createElement("div");
trackerMarker.className = "quiz__marker";
trackerMarker.id = "marker_" i; // specific id for each marker
trackerMarker.setAttribute("data-answer", "");
tracker.appendChild(trackerMarker);
}
и затем не перебирайте каждый маркер — установите цвет для маркера с тем же номером, что и вопрос. Что-то вроде:
document.getElementById("marker_" questionNumber).setAttribute("data-answer", "Correct");
Я не вижу кода для обработки нажатия на кнопку далее, но это не имеет значения для вопроса.
function answerTracker() {
const tracker = document.querySelector(".quiz__sidebar");
// Each quiz contains eight questions
const questions = 8;
for (let i = 1; i <= questions; i ) {
let trackerMarker = document.createElement("div");
trackerMarker.className = "quiz__marker";
trackerMarker.id = "marker_" i;
trackerMarker.setAttribute("data-answer", "");
tracker.appendChild(trackerMarker);
}
}
const runQuiz = (() => {
// Generate answer tracker
answerTracker();
// Set quiz score to zero
let score = 0;
// Get node list of .quiz__marker DIVs
let markers = document.querySelectorAll(".quiz__marker");
// Get node list of answer radio buttons
let answers = document.querySelectorAll(".rsform-radio");
answers.forEach(function(answer) {
answer.addEventListener("click", (e) => {
let target = e.target;
let container = target.closest(".formContainer");
let correct = container.querySelector("div[class$='true']");
let wrong = container.querySelector("div[class$='false']");
let feedback = container.querySelector("div[class$='feedback']");
let question = container.querySelector("div[class*='rsform-block-question']");
let next = container.querySelector(".js-btn--next.success");
if (e.target.value == "t") {
// If answer is correct, increment the user's score by one
score ;
correct.style.display = "block";
wrong.style.display = "none";
feedback.style.display = "block";
document.getElementById("marker_" e.target.dataset.num).setAttribute("data-answer", "Correct");
} else {
correct.style.display = "none";
wrong.style.display = "block";
feedback.style.display = "block";
document.getElementById("marker_" e.target.dataset.num).setAttribute("data-answer", "Incorrect");
}
// If question has been answered, display the next button
if (next !== null amp;amp; next !== "") {
next.style.display = "block";
}
});
});
// If this is the final question in the quiz, assign the score variable to the final-score hidden HTML field
// document.getElementById("final-score").value = score;
})();
.quiz__sidebar .quiz__marker {
display: inline-block;
width: 20px;
height: 20px;
margin: 6px;
background-color: grey;
border-radius: 50%;
}
.quiz__sidebar .quiz__marker[data-answer="Correct"] {
background-color: green;
}
.quiz__sidebar .quiz__marker[data-answer="Incorrect"] {
background-color: red;
}
form.quiz__form .formHidden,
form.quiz__form div[class$="true"],
form.quiz__form div[class$="false"],
form.quiz__form div[class$="feedback"],
form.quiz__form .rsform-block .rsform-button {
display: none;
}
<div class="quiz">
<div class="quiz__sidebar"></div>
<form class="quiz__form">
<div class="formContainer">
<div class="rsform-block-question-one">
<input type="radio" name="form[question-one]" data-num="1" value="f" id="question-one0" class="rsform-radio">
<label for="question-one0">To attract a mate</label>
<br>
<input type="radio" name="form[question-one]" data-num="1" value="t" id="question-one1" class="rsform-radio">
<label for="question-one1">To defend themselves against predators</label>
<br>
<input type="radio" name="form[question-one]" data-num="1" value="f" id="question-one2" class="rsform-radio">
<label for="question-one2">To mark their territory</label>
<br>
<input type="radio" name="form[question-one]" data-num="1" value="f" id="question-one3" class="rsform-radio">
<label for="question-one3">Because they like the smell</label>
</div>
<div class="rsform-block-question-one-true">
<p>
<strong>Correct!</strong>
</p>
</div>
<div class="rsform-block-question-one-false">
<p>
<strong>Nice try</strong>
</p>
</div>
<div class="rsform-block-question-one-feedback">
<p>Skunks spray an extremely offensive odour to make predators go away and leave them alone. If they feel their life is in danger, they have no other defence as they cannot run fast, climb, burrow under the ground, or fight.</p>
</div>
<div class="rsform-block">
<button type="button" class="btn--next js-btn--next rsform-button success button" style="display: none;">
Next
</button>
</div>
</div>
<div class="formContainer formHidden">
<div class="rsform-block-question-two">
<input type="radio" name="form[question-two]" data-num="2" value="f" id="question-two0" class="rsform-radio">
<label for="question-two0">1 cup</label>
<br>
<input type="radio" name="form[question-two]" data-num="2" value="f" id="question-two1" class="rsform-radio">
<label for="question-two1">Endless supply</label>
<br>
<input type="radio" name="form[question-two]" data-num="2" value="t" id="question-two2" class="rsform-radio">
<label for="question-two2">2 tbsp</label>
<br>
<input type="radio" name="form[question-two]" data-num="2" value="f" id="question-two3" class="rsform-radio">
<label for="question-two3">1 tsp</label>
</div>
<div class="rsform-block-question-two-true">
<p>
<strong>Correct!</strong>
</p>
</div>
<div class="rsform-block-question-two-false">
<p>
<strong>Nice try</strong>
</p>
</div>
<div class="rsform-block-question-two-feedback">
<p>Skunks have only 2 tbsp (30ml) of spray and it takes them more than a week to re-supply. They cannot spray every day as they will simply run out. Skunks use spraying as a last resort only as if they run out, they are defenceless against predators.</p>
</div>
<div class="rsform-block">
<button type="button" class="btn--next js-btn--next rsform-button success button" style="display: none;">
Next
</button>
</div>
</div>
</form>
</div>
Комментарии:
1. Спасибо за ваш код. Я реализовал это на своем промежуточном сайте, но получаю эту ошибку JS в Chrome: Uncaught TypeError: не удается прочитать свойство ‘setAttribute’ null в строке 58 из quiz.js . Вот промежуточная ссылка . Я также обновил свой вопрос с помощью полного JS из quiz.js для ознакомления.
2. Пожалуйста, проигнорируйте мой первый комментарий. Я полностью пропустил
data-num
атрибут, который вы добавили к переключателям. Я добавил его, и теперь код работает.