嗯,你的代码有很多错误。但是,您走对了!
注意事项:
- 您可以在页面加载事件之外声明您的函数。
- 添加事件侦听器时,您必须传递函数,不调用。
试试这个:
//The load event is fired when the whole page has loaded
window.addEventListener("load",function() {
//Get all buttons in the page
let buttons = document.querySelectorAll('button');
//Set a click event listener for each button
//When the event occurs then it calls the checkAnswer event handler callback and passes the event to it
//Notice that the callback function is passed and not directly called with "()"!
buttons.forEach(b => b.addEventListener("click",checkAnswer));
});
//Check answer function
function checkAnswer(event) { // <- here we get the event and use it
//Get the presses button
var buttonPressed = event.target;
//Check the content of the button
if (buttonPressed.innerHTML == 'Uruguay') {
//Change background to green
buttonPressed.style.background = "green";
} else {
//Change background to red
buttonPressed.style.background = "red";
}
}
编辑:
关于安全方面。在提供的两种代码(您的和您朋友的)中,用户都可以操作 HTML 中的数据并获得正确的答案。此类检查必须在服务器端进行,您可以告诉服务器检查用户发送的值(单击按钮的值)是否正确。然后根据服务器的答案继续显示所选按钮/答案是否正确。
,
只是为了向您展示作为 JavaScript 的语言之美 - 这里有两种可能的方法(真的很多),一种简单,另一种高级 strong> 使用动态模板生成 - 全部来自代码中预定义的一些数据模型:
1。更简单的解决方案:
在父元素上使用 data-*
属性来存储正确的答案字符串。
只需将您的按钮放入 HTML 并将正确的答案值分配给父元素 data-answer
属性:
const ELS_answer = document.querySelectorAll("[data-answer]");
ELS_answer.forEach(EL => {
// Assign click handler to parent element with data-answer attribute
EL.addEventListener("click",(ev) => {
// Get the data attribute of the parent element
const correct = ev.currentTarget.dataset.answer;
// Get the text of the clicked button
const answer = ev.target.closest("button").textContent;
// Check if correct
if (answer === correct) {
alert("CORRECT! (PS: make button green here!)");
} else {
alert("Not correct :(");
}
});
});
<div data-answer="Five">
<h3>What goes after "Four"?</h3>
<button type="button">One</button>
<button type="button">Five</button>
<button type="button">Nine</button>
</div>
<div data-answer="nice">
<h3>This site is pretty ____</h3>
<button type="button">nice</button>
<button type="button">boring</button>
<button type="button">sweet</button>
</div>
<div data-answer="8">
<h3>How many bits are in a single byte?</h3>
<button type="button">4</button>
<button type="button">8</button>
<button type="button">16</button>
</div>
正如您在上面看到的,您不会用字符串污染您的 JavaScript 代码逻辑,并且该代码可以用于无限数量的琐事( “多项选择”)问题和按钮。
2.高级解决方案
请记住 - 数据!
那么您将如何为{{3 }}?您有多个按钮(因此可以将其视为一个数组),而您只有一个正确答案。
而且您还有类型(目前有两种:多项选择和自由响应),因此type
、question
、{ {1}}、answers
都可以是 correct
数组内每个 Object item 的属性。
可以这样建模:
trivia
鉴于以上内容,您可以迭代 const trivia = [
{
// `type` will help you create specific HTML Elements markup (template)
type: "multiple",// The question that goes into H3
question: "What is the first word of the well known typesetting text?",// Loop this Array values to generate your buttons!
answers: ["Ipsum","Lorem","Amet","Sit","Dolor"],// Here you can store the correct answer
correct: "Lorem",},{
type: "free",question: "What is the best community driven website for developers?",answers: [],// will be populated by user!
correct: "Stack Overflow",];
数组并生成 HTML。
如果当前迭代的琐事项目 trivia
是 type
- 生成 "multiple"
和您的按钮。
如果当前迭代的琐事项目 <h3>
是 type
- 生成 "free"
、<h3>
和按钮。
<input type="text">
鉴于以上内容,您可以提出任意数量的琐事问题。
将来您可以扩展上述数据以获得其他有趣的// Trivia HTML templates functions:
const templates = {
multiple(data) { /* GENETATE THE "MULTIPLE" TEMPLATE and append to DOM */ },free(data) { /* GENETATE THE "FREE" TEMPLATE and append to DOM */ },// In the future you can add more template types here
};
// Iterate your trivia objects and generate HTML
trivia.forEach((data) => {
templates[data.type](data); // call a specific template generator!
});
。
要生成按钮,您需要做的就是迭代 type
如下:
data.answers
const trivia = [
{
type: "multiple",question: "What is the first word of the well known typesetting text?",answers: ["Ipsum",correct: "Lorem",{
type: "free",answers: [],correct: "Stack Overflow",];
// Utility functions
// Create a new Element tag with properties:
const newEL = (tag,props) => Object.assign(document.createElement(tag),props);
// Trivia HTML templates:
const templates = {
multiple(data) {
// Create the Heading
const H3 = newEL("h3",{textContent: data.question});
// Create the Buttons
const BUTTONS = data.answers.reduce((DF,answer) => {
// Create a single button
const BUTTON = newEL("button",{
type:"button",textContent: answer,onclick() {
// check if answer is correct
if (data.correct === this.textContent) {
alert("CORRECT! PS: style your button green here");
} else {
alert("Not norrect");
}
}
});
DF.append(BUTTON); // Append every button to the DocumentFragment
return DF; // Return the DocumentFragment
},new DocumentFragment());
// Finally,append everything to a specific DOM Element parent
document.querySelector("#multiple").append(H3,BUTTONS);
},free(data) {
// TODO!
// Similar as the above one
// You can do it!!!
}
};
// Iterate your trivia objects and generate HTML templates
trivia.forEach((data) => templates[data.type](data));
关于安全/黑客
在此阶段,对于此实验室任务,您无需担心安全性。但很高兴您始终牢记这一点,因为它极其重要!
因为到达浏览器的代码(HTML、JS、网络请求等)可以被欺骗或反向工程(如上面的示例 1。在 HTML 中硬编码了答案;和示例 2。它们是正确的在 JS 中),为了不允许用户看到正确的答案,正确的方法是将正确的答案存储在服务器上的某个地方(用户不可见)。将用户选择的答案发送到服务器并在服务器端检查正确性。服务器应该只响应浏览器的响应(即:<div id="multiple"></div>
/ "correct"
),以便用户界面可以前进到下一个问题或给出最终的总分。即便如此,服务器也不应该信任用户!因此,您应该使用浏览器+后端技术实现一种用户会话,例如:会话 cookie,并检查来自用户的数据是否与该特定用户的数据库中的状态(当前问题,正确的问题计数,时间戳等)。
不是 CS50 实验室现阶段必须解决的主题或问题。但如果您愿意 - 没有人会阻止您自行探索和实施更强大、更安全的解决方案!
本文链接:https://www.f2er.com/477294.html