Javascript 循环中的 CreateElement 在按下按钮时返回到上一个循环值?
Javascript CreateElement in loop go back to previous looped value when button is pressed?
我正在做一个类似形式的测验项目。你会得到多个问题和答案,你可以点击任何答案来创建个人结果。我已经问过一个关于这个项目的问题,因为我真的不知道如何正确循环并且我解决了这个问题,但它仍然不是很好。现在我正在创建一个上一个按钮,它有点用,但不是很好。
我的代码:
<div class="container">
<div id="question"></div>
<div id="answer"></div>
<button onclick="NextQuestion()" id="nextbtn">Next</button>
<button onclick="PrevQuestion()" id="prevbtn">Previous</button>
<div id="finalLink"></div>
</div>
JS
class QuizPart{
constructor(questionDescription, chosenAnswer, prefix){
this.questionDescription = questionDescription;
this.chosenAnswer = chosenAnswer;
this.prefix = prefix;
}
}
class ChosenAnswer{
constructor(id, name){
this.id = id;
this.name = name;
}
}
let Quiz = [
new QuizPart('Whats your size?', [
new ChosenAnswer('6595', '41'),
new ChosenAnswer('6598', '42'),
new ChosenAnswer('6601', '43'),
], 'bd_shoe_size_ids='),
new QuizPart('What color would you like?', [
new ChosenAnswer('6053', 'Red'),
new ChosenAnswer('6044', 'Blue'),
new ChosenAnswer('6056', 'Yellow'),
new ChosenAnswer('6048', 'Green'),
], 'color_ids='),
new QuizPart('What brand would you like?', [
new ChosenAnswer('5805', 'Adidas'),
new ChosenAnswer('5866', 'Nike'),
new ChosenAnswer('5875', 'Puma'),
], 'manufacturer_ids='),
]
// console.log(Quiz);
let url = [];
let questionNumber = 0;
let button = document.getElementById('answer');
let questionName = document.getElementById('question');
let nextbtn = document.getElementById('nextbtn');
let prevbtn = document.getElementById('prevbtn')
let resultbtn = document.getElementById('FLink');
function NextQuestion() {
let oldAnswerButton = document.querySelectorAll('.filter_anwser');
// Deletes old question when the next question is clicked
for (let answerButton of oldAnswerButton) {
answerButton.style.display = 'none';
}
let question = Quiz[questionNumber];
// Displays answers of the questions
for (let y = 0; y < question.chosenAnswer.length; y++) {
let item = question.chosenAnswer[y];
// Display answer buttons
let btn = document.createElement('button');
btn.value = item.id;
btn.className = "filter_anwser";
btn.textContent = item.name;
button.appendChild(btn);
}
// Check if your at the last question so the next button will stop being displayed.
if (Quiz.length - 1 === questionNumber) {
nextbtn.style.display = 'none';
resultbtn.style.display = 'grid';
}
// Displays Question
questionName.textContent = question.questionDescription;
questionName.id = "questionID";
// adds 1 to question to see a different question
questionNumber++;
}
function PrevQuestion(){
questionNumber--;
let oldAnswerButton = document.querySelectorAll('.filter_anwser');
// Deletes old question when the next question is clicked
for (let answerButton of oldAnswerButton) {
answerButton.style.display = 'none';
}
let question = Quiz[questionNumber];
// Displays answers of the questions
for (let y = 0; y < question.chosenAnswer.length; y++) {
let item = question.chosenAnswer[y];
// Display answer buttons
let btn = document.createElement('button');
btn.value = item.id;
btn.className = "filter_anwser";
btn.textContent = item.name;
button.appendChild(btn);
}
//Check if your at the last question so the next button will stop being displayed.
if (Quiz.length === questionNumber) {
prevbtn.style.display = 'none';
resultbtn.style.display = 'grid';
}
// Displays Question
questionName.textContent = question.questionDescription;
questionName.id = "questionID";
}
现在,正如您所见,我在按下上一个按钮时创建了一个新元素(也见下图):
我尝试不创建一组全新的元素,而是返回到上一组。我试着用一个简单的 if 语句来做这件事,比如:
let i = 0;
if (i < question.chosenAnswer[y]){
y--;
}
这只是我尝试过但没有奏效的方法。有人可以帮我做这个吗?
保存信息:
function getLink(url) {
let tmp = [];
for (let i = 0; i < url.length; i++) {
// Check if question is from the same quiz part and adds a , between chosen answers and add the right prefix at the beginning
if (url[i].length > 0){
tmp.push("" + Quiz[i].prefix + url[i].join(","))
}
}
/// If answers are from different quiz parts add a & between answers.
console.log(url, questionNumber);
return "" + tmp.join("&");
};
button.addEventListener("click", function (e) {
const tgt = e.target;
// clear the url array if there's nothing clicked
if (url.length < questionNumber) {
url.push([]);
}
let quizUrl = url[questionNumber - 1];
// Check if a button is clicked. Changes color and adds value to the url array.
if (quizUrl.indexOf(tgt.value) === -1) {
quizUrl.push(tgt.value);
e.target.style.backgroundColor = "orange";
// Check if a button is clicked again. If clicked again changes color back and deletes value in the url array.
} else {
quizUrl.splice(quizUrl.indexOf(tgt.value), 1);
e.target.style.backgroundColor = "white";
}
console.log(getLink(url));
})
您需要使用 element.remove() 而不是 element.style.display =""none"
为什么?
element.remove() - 将完全删除 DOM 元素。
element.style.display ="none" - 只会对最终用户隐藏它。但它仍然会在 DOM 树上。
Js Fiddle 以下解决方案:
还修复了您代码中的一些问题。在我修复的地方添加了注释行
- 上一个问题上的下一步按钮现在消失了
- 第一个问题上的上一个按钮现在消失了
编辑:
编辑了代码片段,几乎没有逻辑更改。
现在答案按预期保存在数组中。
虽然按钮不保留颜色。这可以在上一个和下一个按钮单击函数中以与完成 getLinks 方法相同的方式处理。
class QuizPart{
constructor(questionDescription, chosenAnswer, prefix){
this.questionDescription = questionDescription;
this.chosenAnswer = chosenAnswer;
this.prefix = prefix;
}
}
class ChosenAnswer{
constructor(id, name){
this.id = id;
this.name = name;
}
}
let Quiz = [
new QuizPart('Whats your size?', [
new ChosenAnswer('6595', '41'),
new ChosenAnswer('6598', '42'),
new ChosenAnswer('6601', '43'),
], 'bd_shoe_size_ids='),
new QuizPart('What color would you like?', [
new ChosenAnswer('6053', 'Red'),
new ChosenAnswer('6044', 'Blue'),
new ChosenAnswer('6056', 'Yellow'),
new ChosenAnswer('6048', 'Green'),
], 'color_ids='),
new QuizPart('What brand would you like?', [
new ChosenAnswer('5805', 'Adidas'),
new ChosenAnswer('5866', 'Nike'),
new ChosenAnswer('5875', 'Puma'),
], 'manufacturer_ids='),
]
//console.log(Quiz);
let url = [];
//FIX - INIT VALUE UPDATED TO -1
let questionNumber = -1;
let button = document.getElementById('answer');
let questionName = document.getElementById('question');
let nextbtn = document.getElementById('nextbtn');
let prevbtn = document.getElementById('prevbtn')
let resultbtn = document.getElementById('finalLink');
function NextQuestion() {
//FIX - PUSHED THIS LINE UP HERE TO HAVE SYNCED LOGIC
// adds 1 to question to see a different question
questionNumber++;
let oldAnswerButton = document.querySelectorAll('.filter_anwser');
// Deletes old question when the next question is clicked
for (let answerButton of oldAnswerButton) {
//CORRECTION DONE HERE
answerButton.remove();
}
let question = Quiz[questionNumber];
// Displays answers of the questions
for (let y = 0; y < question.chosenAnswer.length; y++) {
let item = question.chosenAnswer[y];
// Display answer buttons
let btn = document.createElement('button');
btn.value = item.id;
btn.className = "filter_anwser";
btn.textContent = item.name;
button.appendChild(btn);
}
//FIX -FOR NEXT BUTTON AND PREVIOUS BUTTON CHANGES
// Check if your at the last question so the next button will stop being displayed.
if (questionNumber > 0 ) {
prevbtn.style.display = 'grid'
}else{
prevbtn.style.display = 'none'
}
if (Quiz.length - 1 <= questionNumber) {
nextbtn.style.display = 'none';
resultbtn.style.display = 'grid';
}else{
nextbtn.style.display = 'grid';
}
// Displays Question
questionName.textContent = question.questionDescription;
questionName.id = "questionID";
}
function PrevQuestion(){
questionNumber--;
let oldAnswerButton = document.querySelectorAll('.filter_anwser');
// Deletes old question when the next question is clicked
for (let answerButton of oldAnswerButton) {
//CORRECTION DONE HERE
answerButton.remove();
}
let question = Quiz[questionNumber];
// Displays answers of the questions
for (let y = 0; y < question.chosenAnswer.length; y++) {
let item = question.chosenAnswer[y];
// Display answer buttons
let btn = document.createElement('button');
btn.value = item.id;
btn.className = "filter_anwser";
btn.textContent = item.name;
button.appendChild(btn);
}
//FIX - FOR NEXT BUTTON AND PREVIOUS BUTTON CHANGES
//Check if your at the last question so the prev button will stop being displayed.
console.log(questionNumber);
if (questionNumber < Quiz.length - 1) {
nextbtn.style.display = 'grid';
}
if (questionNumber <= 0) {
prevbtn.style.display = 'none';
}else{
prevbtn.style.display = 'grid';
}
// Displays Question
questionName.textContent = question.questionDescription;
questionName.id = "questionID";
}
function getLink(url) {
let tmp = [];
for (let i = 0; i < url.length; i++) {
// Check if question is from the same quiz part and adds a , between chosen answers and add the right prefix at the beginning
if (url[i].length > 0){
tmp.push("" + Quiz[i].prefix + url[i].join(","))
}
}
/// If answers are from different quiz parts add a & between answers.
console.log(url, questionNumber);
return "" + tmp.join("&");
};
button.addEventListener("click", function (e) {
const tgt = e.target;
//FIX - CLICK HANDLING ONLY FOR YOUR answer BUTTONS
if("filter_anwser" == e.target.className){
//FIX - since Counter logic was update above, hence updated condition check here too
// clear the url array if there's nothing clicked
if (url.length < questionNumber + 1) {
url.push([]);
}
let quizUrl = url[questionNumber];
// Check if a button is clicked. Changes color and adds value to the url array.
if (quizUrl.indexOf(tgt.value) === -1) {
quizUrl.push(tgt.value);
e.target.style.backgroundColor = "orange";
// Check if a button is clicked again. If clicked again changes color back and deletes value in the url array.
} else {
quizUrl.splice(quizUrl.indexOf(tgt.value), 1);
e.target.style.backgroundColor = "white";
}
console.log(getLink(url));
}
})
<div class="container">
<div id="question"></div>
<div id="answer"></div>
<button onclick="NextQuestion()" id="nextbtn">Next</button>
<!--At first there should not be a previous button Hence update this-->
<button onclick="PrevQuestion()" id="prevbtn">Previous</button>
<div id="finalLink"></div>
</div>
您必须检索以前创建的按钮才能显示(*)它们。
例如,您可以使用放在 value
属性中的 id
检索它们:
for (let y = 0; y < question.chosenAnswer.length; y++) {
let item = question.chosenAnswer[y];
// retrieve the button by it's value="id" attribute
let btn = document.querySelector('button[value="' + item.id + '"]');
btn.style.display = 'grid';
}
(*) 请注意,当您说“删除问题”时,您实际上只是隐藏它们,而不是删除(即从文档中删除)。
我正在做一个类似形式的测验项目。你会得到多个问题和答案,你可以点击任何答案来创建个人结果。我已经问过一个关于这个项目的问题,因为我真的不知道如何正确循环并且我解决了这个问题,但它仍然不是很好。现在我正在创建一个上一个按钮,它有点用,但不是很好。
我的代码:
<div class="container">
<div id="question"></div>
<div id="answer"></div>
<button onclick="NextQuestion()" id="nextbtn">Next</button>
<button onclick="PrevQuestion()" id="prevbtn">Previous</button>
<div id="finalLink"></div>
</div>
JS
class QuizPart{
constructor(questionDescription, chosenAnswer, prefix){
this.questionDescription = questionDescription;
this.chosenAnswer = chosenAnswer;
this.prefix = prefix;
}
}
class ChosenAnswer{
constructor(id, name){
this.id = id;
this.name = name;
}
}
let Quiz = [
new QuizPart('Whats your size?', [
new ChosenAnswer('6595', '41'),
new ChosenAnswer('6598', '42'),
new ChosenAnswer('6601', '43'),
], 'bd_shoe_size_ids='),
new QuizPart('What color would you like?', [
new ChosenAnswer('6053', 'Red'),
new ChosenAnswer('6044', 'Blue'),
new ChosenAnswer('6056', 'Yellow'),
new ChosenAnswer('6048', 'Green'),
], 'color_ids='),
new QuizPart('What brand would you like?', [
new ChosenAnswer('5805', 'Adidas'),
new ChosenAnswer('5866', 'Nike'),
new ChosenAnswer('5875', 'Puma'),
], 'manufacturer_ids='),
]
// console.log(Quiz);
let url = [];
let questionNumber = 0;
let button = document.getElementById('answer');
let questionName = document.getElementById('question');
let nextbtn = document.getElementById('nextbtn');
let prevbtn = document.getElementById('prevbtn')
let resultbtn = document.getElementById('FLink');
function NextQuestion() {
let oldAnswerButton = document.querySelectorAll('.filter_anwser');
// Deletes old question when the next question is clicked
for (let answerButton of oldAnswerButton) {
answerButton.style.display = 'none';
}
let question = Quiz[questionNumber];
// Displays answers of the questions
for (let y = 0; y < question.chosenAnswer.length; y++) {
let item = question.chosenAnswer[y];
// Display answer buttons
let btn = document.createElement('button');
btn.value = item.id;
btn.className = "filter_anwser";
btn.textContent = item.name;
button.appendChild(btn);
}
// Check if your at the last question so the next button will stop being displayed.
if (Quiz.length - 1 === questionNumber) {
nextbtn.style.display = 'none';
resultbtn.style.display = 'grid';
}
// Displays Question
questionName.textContent = question.questionDescription;
questionName.id = "questionID";
// adds 1 to question to see a different question
questionNumber++;
}
function PrevQuestion(){
questionNumber--;
let oldAnswerButton = document.querySelectorAll('.filter_anwser');
// Deletes old question when the next question is clicked
for (let answerButton of oldAnswerButton) {
answerButton.style.display = 'none';
}
let question = Quiz[questionNumber];
// Displays answers of the questions
for (let y = 0; y < question.chosenAnswer.length; y++) {
let item = question.chosenAnswer[y];
// Display answer buttons
let btn = document.createElement('button');
btn.value = item.id;
btn.className = "filter_anwser";
btn.textContent = item.name;
button.appendChild(btn);
}
//Check if your at the last question so the next button will stop being displayed.
if (Quiz.length === questionNumber) {
prevbtn.style.display = 'none';
resultbtn.style.display = 'grid';
}
// Displays Question
questionName.textContent = question.questionDescription;
questionName.id = "questionID";
}
现在,正如您所见,我在按下上一个按钮时创建了一个新元素(也见下图):
我尝试不创建一组全新的元素,而是返回到上一组。我试着用一个简单的 if 语句来做这件事,比如:
let i = 0;
if (i < question.chosenAnswer[y]){
y--;
}
这只是我尝试过但没有奏效的方法。有人可以帮我做这个吗?
保存信息:
function getLink(url) {
let tmp = [];
for (let i = 0; i < url.length; i++) {
// Check if question is from the same quiz part and adds a , between chosen answers and add the right prefix at the beginning
if (url[i].length > 0){
tmp.push("" + Quiz[i].prefix + url[i].join(","))
}
}
/// If answers are from different quiz parts add a & between answers.
console.log(url, questionNumber);
return "" + tmp.join("&");
};
button.addEventListener("click", function (e) {
const tgt = e.target;
// clear the url array if there's nothing clicked
if (url.length < questionNumber) {
url.push([]);
}
let quizUrl = url[questionNumber - 1];
// Check if a button is clicked. Changes color and adds value to the url array.
if (quizUrl.indexOf(tgt.value) === -1) {
quizUrl.push(tgt.value);
e.target.style.backgroundColor = "orange";
// Check if a button is clicked again. If clicked again changes color back and deletes value in the url array.
} else {
quizUrl.splice(quizUrl.indexOf(tgt.value), 1);
e.target.style.backgroundColor = "white";
}
console.log(getLink(url));
})
您需要使用 element.remove() 而不是 element.style.display =""none"
为什么? element.remove() - 将完全删除 DOM 元素。 element.style.display ="none" - 只会对最终用户隐藏它。但它仍然会在 DOM 树上。
Js Fiddle 以下解决方案:
还修复了您代码中的一些问题。在我修复的地方添加了注释行
- 上一个问题上的下一步按钮现在消失了
- 第一个问题上的上一个按钮现在消失了
编辑:
编辑了代码片段,几乎没有逻辑更改。 现在答案按预期保存在数组中。 虽然按钮不保留颜色。这可以在上一个和下一个按钮单击函数中以与完成 getLinks 方法相同的方式处理。
class QuizPart{
constructor(questionDescription, chosenAnswer, prefix){
this.questionDescription = questionDescription;
this.chosenAnswer = chosenAnswer;
this.prefix = prefix;
}
}
class ChosenAnswer{
constructor(id, name){
this.id = id;
this.name = name;
}
}
let Quiz = [
new QuizPart('Whats your size?', [
new ChosenAnswer('6595', '41'),
new ChosenAnswer('6598', '42'),
new ChosenAnswer('6601', '43'),
], 'bd_shoe_size_ids='),
new QuizPart('What color would you like?', [
new ChosenAnswer('6053', 'Red'),
new ChosenAnswer('6044', 'Blue'),
new ChosenAnswer('6056', 'Yellow'),
new ChosenAnswer('6048', 'Green'),
], 'color_ids='),
new QuizPart('What brand would you like?', [
new ChosenAnswer('5805', 'Adidas'),
new ChosenAnswer('5866', 'Nike'),
new ChosenAnswer('5875', 'Puma'),
], 'manufacturer_ids='),
]
//console.log(Quiz);
let url = [];
//FIX - INIT VALUE UPDATED TO -1
let questionNumber = -1;
let button = document.getElementById('answer');
let questionName = document.getElementById('question');
let nextbtn = document.getElementById('nextbtn');
let prevbtn = document.getElementById('prevbtn')
let resultbtn = document.getElementById('finalLink');
function NextQuestion() {
//FIX - PUSHED THIS LINE UP HERE TO HAVE SYNCED LOGIC
// adds 1 to question to see a different question
questionNumber++;
let oldAnswerButton = document.querySelectorAll('.filter_anwser');
// Deletes old question when the next question is clicked
for (let answerButton of oldAnswerButton) {
//CORRECTION DONE HERE
answerButton.remove();
}
let question = Quiz[questionNumber];
// Displays answers of the questions
for (let y = 0; y < question.chosenAnswer.length; y++) {
let item = question.chosenAnswer[y];
// Display answer buttons
let btn = document.createElement('button');
btn.value = item.id;
btn.className = "filter_anwser";
btn.textContent = item.name;
button.appendChild(btn);
}
//FIX -FOR NEXT BUTTON AND PREVIOUS BUTTON CHANGES
// Check if your at the last question so the next button will stop being displayed.
if (questionNumber > 0 ) {
prevbtn.style.display = 'grid'
}else{
prevbtn.style.display = 'none'
}
if (Quiz.length - 1 <= questionNumber) {
nextbtn.style.display = 'none';
resultbtn.style.display = 'grid';
}else{
nextbtn.style.display = 'grid';
}
// Displays Question
questionName.textContent = question.questionDescription;
questionName.id = "questionID";
}
function PrevQuestion(){
questionNumber--;
let oldAnswerButton = document.querySelectorAll('.filter_anwser');
// Deletes old question when the next question is clicked
for (let answerButton of oldAnswerButton) {
//CORRECTION DONE HERE
answerButton.remove();
}
let question = Quiz[questionNumber];
// Displays answers of the questions
for (let y = 0; y < question.chosenAnswer.length; y++) {
let item = question.chosenAnswer[y];
// Display answer buttons
let btn = document.createElement('button');
btn.value = item.id;
btn.className = "filter_anwser";
btn.textContent = item.name;
button.appendChild(btn);
}
//FIX - FOR NEXT BUTTON AND PREVIOUS BUTTON CHANGES
//Check if your at the last question so the prev button will stop being displayed.
console.log(questionNumber);
if (questionNumber < Quiz.length - 1) {
nextbtn.style.display = 'grid';
}
if (questionNumber <= 0) {
prevbtn.style.display = 'none';
}else{
prevbtn.style.display = 'grid';
}
// Displays Question
questionName.textContent = question.questionDescription;
questionName.id = "questionID";
}
function getLink(url) {
let tmp = [];
for (let i = 0; i < url.length; i++) {
// Check if question is from the same quiz part and adds a , between chosen answers and add the right prefix at the beginning
if (url[i].length > 0){
tmp.push("" + Quiz[i].prefix + url[i].join(","))
}
}
/// If answers are from different quiz parts add a & between answers.
console.log(url, questionNumber);
return "" + tmp.join("&");
};
button.addEventListener("click", function (e) {
const tgt = e.target;
//FIX - CLICK HANDLING ONLY FOR YOUR answer BUTTONS
if("filter_anwser" == e.target.className){
//FIX - since Counter logic was update above, hence updated condition check here too
// clear the url array if there's nothing clicked
if (url.length < questionNumber + 1) {
url.push([]);
}
let quizUrl = url[questionNumber];
// Check if a button is clicked. Changes color and adds value to the url array.
if (quizUrl.indexOf(tgt.value) === -1) {
quizUrl.push(tgt.value);
e.target.style.backgroundColor = "orange";
// Check if a button is clicked again. If clicked again changes color back and deletes value in the url array.
} else {
quizUrl.splice(quizUrl.indexOf(tgt.value), 1);
e.target.style.backgroundColor = "white";
}
console.log(getLink(url));
}
})
<div class="container">
<div id="question"></div>
<div id="answer"></div>
<button onclick="NextQuestion()" id="nextbtn">Next</button>
<!--At first there should not be a previous button Hence update this-->
<button onclick="PrevQuestion()" id="prevbtn">Previous</button>
<div id="finalLink"></div>
</div>
您必须检索以前创建的按钮才能显示(*)它们。
例如,您可以使用放在 value
属性中的 id
检索它们:
for (let y = 0; y < question.chosenAnswer.length; y++) {
let item = question.chosenAnswer[y];
// retrieve the button by it's value="id" attribute
let btn = document.querySelector('button[value="' + item.id + '"]');
btn.style.display = 'grid';
}
(*) 请注意,当您说“删除问题”时,您实际上只是隐藏它们,而不是删除(即从文档中删除)。