如何在两个选择不相同的情况下为用户生成四个选择?
How to generate four choices for users without two choices being the same?
我正在使用 API 创建动漫测验。我还使用 Math.random() 创建四个选项供用户单击。但我面临两个问题。首先,当向用户呈现第一组 4 个选择时,有可能其中两个是相同的。我希望所有四个选择都彼此不同。其次,无论用户是否获得正确答案,我都希望生成另一组四个不同的问题。我试图想出一些东西,但它很快变成了意大利面条代码。
const animeApi = "https://anime-facts-rest-api.herokuapp.com/api/v1";
const intro = document.querySelector(".intro");
const anime_picture = document.querySelector(".anime_picture img");
const anime = document.querySelector(".anime");
const questions = Array.from(document.querySelector(".question").children)
const question1 = document.querySelector(".question1");
const question2 = document.querySelector(".question2");
const question3 = document.querySelector(".question3");
const question4 = document.querySelector(".question4");
const question5 = document.querySelector(".question5");
const randomNum1 = Math.floor((Math.random()* 13));
const randomNum2 = Math.floor((Math.random()* 13));
const randomNum3 = Math.floor((Math.random()* 13));
const randomNum4 = Math.floor((Math.random()* 13));
let [counter, score] = [0,0]
let data;
fetch(animeApi)
.then(res => res.json())
.then(response => {
// response is an object but we need the array in property data
console.log(response)
data = response.data;
console.log(data.length)
for (let {anime_img} of data) {
console.log(anime_img)
}
// alternative
//data.forEach(item => console.log(item));
});
intro.addEventListener("click", () => {
intro.classList.add("hide");
anime.classList.remove("hide");
anime.classList.add("show")
quiz()
});
function quiz() {
anime_picture.src = data[counter].anime_img;
question1.innerHTML = data[randomNum1].anime_name;
question2.innerHTML = data[randomNum2].anime_name;
question3.innerHTML = data[randomNum3].anime_name;
question4.innerHTML = data[randomNum4].anime_name;
}
for(var i = 0; i < questions.length; i++) {
questions[i].addEventListener("click", userAnswer)
}
function userAnswer(e) {
let target = e.target.innerHTML
if(target === data[counter].anime_name) {
console.log("correct");
score++
} else {
console.log("incorrect");
}
update();
}
function update () {
if(counter < data.length) {
counter++;
quiz();
}
}
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>
组合随机选择问题的函数也可以使用 splice
数组方法 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)
从其数组中删除该问题
删除的元素可以添加到新数组中以跟踪使用过的问题。
这涉及防止在四人一组和随后的四人一组中重复。
在代码片段中,我使用了一组数字来代替问题,但逻辑是相同的。
请注意,每次添加后控制台都会记录问题数组,显示已使用的元素已被删除。
const questions = [1,2,3,4,5,6,7,8,9,10,11,12];
const usedQuestions = [];
const outputField = document.getElementById("output");
function next4() {
let qPanel = document.createElement('p');
for(let i=0; i<4; i++) {
if (questions.length > 0) {
let index = Math.floor(Math.random()*questions.length);
qPanel.innerHTML = qPanel.innerHTML + `question ${questions[index]}, `;
usedQuestions.push(questions[index]);
questions.splice(index,1);
} // end if array has length;
} // next i question;
outputField.appendChild(qPanel)
console.log(questions)
} // end function next4;
<button onclick="next4()">next set</button>
<div id="output"></output>
可能需要 'full page' link 才能查看页面和控制台。
我几乎没有重构您的代码并修复了错误。现在你可以获得 4 个随机答案,但保证有正确答案。此外,现在答案的数量取决于 div
和 class answer
:
的计数
const animeApi = 'https://anime-facts-rest-api.herokuapp.com/api/v1';
const intro = document.querySelector('.intro');
const anime_picture = document.querySelector('.anime_picture img');
const anime = document.querySelector('.anime');
const answers = [...document.querySelectorAll('.answer')];
let data = [];
let [counter, score] = [0, 0];
fetch(animeApi)
.then(res => res.json())
.then(response => data = response.data);
const getRandomNumber = () => Math.floor(Math.random() * data.length);
intro.addEventListener('click', () => {
intro.classList.add('hide');
anime.classList.remove('hide');
anime.classList.add('show');
quiz();
});
const getUniqueAnswersNumbers = (count) => {
const answersNumbers = new Set();
while(!answersNumbers.has(counter)) {
answersNumbers.clear();
while (answersNumbers.size < count) answersNumbers.add(getRandomNumber());
}
return [...answersNumbers];
}
function quiz() {
anime_picture.src = data[counter].anime_img;
const answersNumbers = getUniqueAnswersNumbers(answers.length);
answers.forEach((answer, i) => answer.innerHTML = data[answersNumbers[i]].anime_name);
}
answers.forEach(answer => answer.addEventListener('click', userAnswer));
function userAnswer(e) {
const target = e.target.innerHTML;
if(target === data[counter].anime_name) {
console.log('correct');
++score;
} else {
console.log('incorrect');
}
update();
}
function update () {
if((counter + 1) === data.length) return;
++counter;
quiz();
}
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;
}
.answers {
height: 100px;
width: 100%;
border: 1px blue solid;
bottom: 0;
position: absolute;
display: flex;
justify-content: space-around;
align-items: center;
}
.answers > 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="answers">
<div class="answer answer1"></div>
<div class="answer answer2"></div>
<div class="answer answer3"></div>
<div class="answer answer4"></div>
</div>
<header>anime Quiz</header>
</div>
</body>
<script src="index.js" type="text/javascript"></script>
</html>
我正在使用 API 创建动漫测验。我还使用 Math.random() 创建四个选项供用户单击。但我面临两个问题。首先,当向用户呈现第一组 4 个选择时,有可能其中两个是相同的。我希望所有四个选择都彼此不同。其次,无论用户是否获得正确答案,我都希望生成另一组四个不同的问题。我试图想出一些东西,但它很快变成了意大利面条代码。
const animeApi = "https://anime-facts-rest-api.herokuapp.com/api/v1";
const intro = document.querySelector(".intro");
const anime_picture = document.querySelector(".anime_picture img");
const anime = document.querySelector(".anime");
const questions = Array.from(document.querySelector(".question").children)
const question1 = document.querySelector(".question1");
const question2 = document.querySelector(".question2");
const question3 = document.querySelector(".question3");
const question4 = document.querySelector(".question4");
const question5 = document.querySelector(".question5");
const randomNum1 = Math.floor((Math.random()* 13));
const randomNum2 = Math.floor((Math.random()* 13));
const randomNum3 = Math.floor((Math.random()* 13));
const randomNum4 = Math.floor((Math.random()* 13));
let [counter, score] = [0,0]
let data;
fetch(animeApi)
.then(res => res.json())
.then(response => {
// response is an object but we need the array in property data
console.log(response)
data = response.data;
console.log(data.length)
for (let {anime_img} of data) {
console.log(anime_img)
}
// alternative
//data.forEach(item => console.log(item));
});
intro.addEventListener("click", () => {
intro.classList.add("hide");
anime.classList.remove("hide");
anime.classList.add("show")
quiz()
});
function quiz() {
anime_picture.src = data[counter].anime_img;
question1.innerHTML = data[randomNum1].anime_name;
question2.innerHTML = data[randomNum2].anime_name;
question3.innerHTML = data[randomNum3].anime_name;
question4.innerHTML = data[randomNum4].anime_name;
}
for(var i = 0; i < questions.length; i++) {
questions[i].addEventListener("click", userAnswer)
}
function userAnswer(e) {
let target = e.target.innerHTML
if(target === data[counter].anime_name) {
console.log("correct");
score++
} else {
console.log("incorrect");
}
update();
}
function update () {
if(counter < data.length) {
counter++;
quiz();
}
}
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>
组合随机选择问题的函数也可以使用 splice
数组方法 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)
删除的元素可以添加到新数组中以跟踪使用过的问题。
这涉及防止在四人一组和随后的四人一组中重复。
在代码片段中,我使用了一组数字来代替问题,但逻辑是相同的。
请注意,每次添加后控制台都会记录问题数组,显示已使用的元素已被删除。
const questions = [1,2,3,4,5,6,7,8,9,10,11,12];
const usedQuestions = [];
const outputField = document.getElementById("output");
function next4() {
let qPanel = document.createElement('p');
for(let i=0; i<4; i++) {
if (questions.length > 0) {
let index = Math.floor(Math.random()*questions.length);
qPanel.innerHTML = qPanel.innerHTML + `question ${questions[index]}, `;
usedQuestions.push(questions[index]);
questions.splice(index,1);
} // end if array has length;
} // next i question;
outputField.appendChild(qPanel)
console.log(questions)
} // end function next4;
<button onclick="next4()">next set</button>
<div id="output"></output>
可能需要 'full page' link 才能查看页面和控制台。
我几乎没有重构您的代码并修复了错误。现在你可以获得 4 个随机答案,但保证有正确答案。此外,现在答案的数量取决于 div
和 class answer
:
const animeApi = 'https://anime-facts-rest-api.herokuapp.com/api/v1';
const intro = document.querySelector('.intro');
const anime_picture = document.querySelector('.anime_picture img');
const anime = document.querySelector('.anime');
const answers = [...document.querySelectorAll('.answer')];
let data = [];
let [counter, score] = [0, 0];
fetch(animeApi)
.then(res => res.json())
.then(response => data = response.data);
const getRandomNumber = () => Math.floor(Math.random() * data.length);
intro.addEventListener('click', () => {
intro.classList.add('hide');
anime.classList.remove('hide');
anime.classList.add('show');
quiz();
});
const getUniqueAnswersNumbers = (count) => {
const answersNumbers = new Set();
while(!answersNumbers.has(counter)) {
answersNumbers.clear();
while (answersNumbers.size < count) answersNumbers.add(getRandomNumber());
}
return [...answersNumbers];
}
function quiz() {
anime_picture.src = data[counter].anime_img;
const answersNumbers = getUniqueAnswersNumbers(answers.length);
answers.forEach((answer, i) => answer.innerHTML = data[answersNumbers[i]].anime_name);
}
answers.forEach(answer => answer.addEventListener('click', userAnswer));
function userAnswer(e) {
const target = e.target.innerHTML;
if(target === data[counter].anime_name) {
console.log('correct');
++score;
} else {
console.log('incorrect');
}
update();
}
function update () {
if((counter + 1) === data.length) return;
++counter;
quiz();
}
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;
}
.answers {
height: 100px;
width: 100%;
border: 1px blue solid;
bottom: 0;
position: absolute;
display: flex;
justify-content: space-around;
align-items: center;
}
.answers > 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="answers">
<div class="answer answer1"></div>
<div class="answer answer2"></div>
<div class="answer answer3"></div>
<div class="answer answer4"></div>
</div>
<header>anime Quiz</header>
</div>
</body>
<script src="index.js" type="text/javascript"></script>
</html>