我想为不同的数组重用现有的循环函数,但要让它在索引之间停止并等待事件侦听器。
问题是这个函数只有在循环完整个数组后才会停止。我还想保留“逐字符”的打字效果。我尝试过使用该功能,但我无法弄清楚。
这是现有的打字效果/循环函数,我还想用它来循环一个名为
questions[]
的不同数组,并让它键入每个字符串并在每个索引之间暂停,等待用户按下按钮,然后得到一个回复。我将使用 buttonOne.addEventListener
输入响应,并触发 questions[]
的下一个问题。
const element =
document.querySelector("div");
const messages =
["Hello, my operating name is Zurlan-42", "more stuff", "more things"];
const typingText = (elem, txt, done = () => {}) => {
let i = 0;
elem.textContent = ""; // Clear before typing
const next = () => {
elem.textContent += txt[i];
if(i === txt.length - 1) return done();
i += 1;
setTimeout(next, 30);
};
next(); // Start
};
const typingArray = (elem, arr, done = () => {}) => {
let i = 0;
const next = () => {
typingText(elem, arr[i], () => {
if(i === arr.length - 1) return done();
i += 1;
setTimeout(next, 2000);
});
};
next(); // Start
}
typingArray(element, messages, () => {
console.log("All Done!");
setTimeout(() => {
element.textContent = "";
}, 2000);
});
<div></div>
这是我到目前为止所拥有的。我不断地在使用 forEach 方法和为每个问题和回答写出每个函数之间来回切换。但是,我觉得循环数组是更好的方法。
const questionOne = () => {
buttonOne.textContent = "No Arms";
buttonTwo.textContent = "No Legs";
buttonOne.addEventListener("click", () => {
console.log("I was clicked!");
})
buttonTwo.addEventListener("click", () => {
console.log("No, I was clicked!");
})
}
questionOne();
实现等待用户输入显示下一条消息的目标的一种方法可能是更改您的typingArray
函数,这样,它将动态创建,而不是等待一段时间过去再进入下一条消息包含这些答案(用户输入)的按钮具有作为单击事件处理程序的逻辑来处理下一个问题。在这里,我将该函数命名为
processQuestions
,并以
index
作为参数,以便当
createAnswerùButtons
创建答案按钮时,它们的单击事件处理程序将进行一次调用,每次调用的索引都指向下一个问题。
const questions = [
{ q: 'Question1.. ?', a: ['Answer1', 'Answer2'] },
{ q: 'Question2.. ?', a: ['Answer1', 'Answer2', 'Answer3'] }
];
const questionElem = document.querySelector('.question');
const answersElem = document.querySelector('.answers');
//this is your original function to type text delaying each character
const typingText = (elem, txt, done = () => {}) => {
let i = 0;
elem.textContent = "";
const next = () => {
elem.textContent += txt[i];
if (i === txt.length - 1) return done();
i += 1;
setTimeout(next, 30);
};
next();
};
//creates the buttons in the .answers area according to the passed answers
const createAnswerButtons = (answers, callback) => {
answers.forEach(answer => {
const button = document.createElement('button');
button.textContent = answer;
button.onclick = callback;
answersElem.appendChild(button);
});
};
const processQuestions = (questions, index = 0) => {
//if there are no more questions
if (index >= questions.length) {
console.log("All questions completed");
return;
}
//get the current question according to the index
const currentQuestion = questions[index];
//instructs your typingText func to start typing the current question
typingText(questionElem, currentQuestion.q, () => {
//and when the typing has been finished,
//create and show the correspondent answer buttons
createAnswerButtons(currentQuestion.a, () => {
//and when one of the answer button was clicked,
//clear the area and pass to the next question
//***here you can put the logic in case you need to keep track of correct answers
questionElem.textContent = '';
answersElem.innerHTML = '';
processQuestions(questions, index + 1);
});
});
};
processQuestions(questions);
<div class="container">
<div class="question"></div>
<div class="answers"></div>
</div>