什么是最好的练习或Java代码的形式(示例)

2022-08-22 00:00:00 javascript html cs50 correctness

我目前正在做CS50。而且我觉得有点迷失了,我不知道做事情或写正确代码的最好方法。 我觉得在C和Python语言中,做事情的线条更清晰。(不要重复代码,使其清晰等)在Java脚本中,我们可以用很多方法来做事情,我不知道哪种方法是正确的。

例如,我花了几天时间处理琐事,这个问题要求我们制作按钮,如果按钮的答案不正确,则会变成红色,如果答案正确,则会变成绿色。我知道,将所有的Java脚本放在一个不同于html的文件中是一个很好的做法,首先我只在html中使用onClick来调用我在js文件中实现的函数,然后我试图将其更改为在html页面中没有任何js代码。

所以我想删除onClick调用,所以,我在加载时将和addEventListener放到javascript中,并执行那里的所有函数,用这个,我想检查按钮的innerHtml是否与正确的答案相同,但这个代码不起作用,我认为这个代码是正确的版本,因为我真的是在检查答案是否正确

window.addEventListener("load", function () {

//Declaring first function

function checkAnswer(event) {

var buttonPressed = event.Target;

if (buttonPressed.innerHTML == 'Uruguay')

{

buttonPressed.style.background = "green";

}

else:

{

buttonPressed.style.background = "red";

}

var buttons = document.querySelectorAll('button');

buttons.forEach(b => b.addEventListener("click", checkAnswer(event)));

}

因为我在这个功能上遇到了问题,所以我请一个使用Java脚本的朋友来查看它,他告诉我有一个简单的方法,根据正确或不正确来标识所有按钮,如果用户点击正确的按钮,执行一个附加到该按钮的函数,将按钮涂成绿色,如果它是红色的,则执行另一个:

const correctButton = document.getElementById("correctButton");

const Incorrectbuttons = document.querySelectorAll("#Incorrectbutton");

bcorrectButton.addEventListener("click", function(){
correctButton.style.background = "green";

});

Incorrectbuttons.forEach(btn => {

btn.addEventListener("click", function(){

btn.style.background = "red";

});

})

我觉得这个代码作弊,因为它实际上并没有检查按钮是否正确,如果用户在浏览器中更改了单词的内部html,按钮仍然变成绿色,在我的代码中,我认为如果用户更改内部html,它不会改变,因为innerHtml与&q;键&q;不匹配。

我不知道我是不是看错了,因为我依附于其他语言的其他思维形式,我可以直接做事情,而不需要Java脚本上的逻辑,或者我的第一个函数完全错误。谢谢!


解决方案

只是为了向您展示一种语言的美妙之处-这里有两种可能的方法(真的),一种是简单的,另一种是更高级的动态模板生成-所有这些都来自代码中预定义的一些数据模型:

1.更简单的解决方案:

使用父元素的data-*属性存储正确的答案字符串。

只需将按钮放入HTML并将正确的答案赋值给父元素data-answer属性:

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
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>

如上所述,您没有用字符串污染您的Java代码逻辑,且该代码可以处理无限数量的琐碎问题和按钮。

2.高级解决方案

记住-数据!

那么,您将如何组织CS50 Lab的第1部分(甚至第2部分&Free Response&)的数据?您有多个按钮(因此可以将其视为数组),并且您只有一个正确答案。
而且您还有类型(当前有两个:多选和自由响应),因此typequestionanswerscorrect都可以是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",
  },

];

考虑到上述情况,您可以迭代trivia数组并生成HTML。

如果当前迭代的琐事项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.answersLike:

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
const trivia = [
  { 
    type:     "multiple",
    question: "What is the first word of the well known typesetting text?",
    answers:  ["Ipsum", "Lorem", "Amet", "Sit", "Dolor"],
    correct:  "Lorem",
  },
  {
    type:     "free",
    question: "What is the best community driven website for developers?",  
    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));
<div id="multiple"></div>

关于安全/黑客

在本实验任务的这个阶段,您不需要担心安全性。但你能一直记住这一点很好,因为它非常重要!

由于到达浏览器的代码(HTML、JS、网络请求等)可以被欺骗或反向生成(如上面的示例1.将答案硬编码为HTML;以及示例2.将它们正确地编码为JS),为了不让用户看到正确的答案,正确的方法是将正确的答案存储在您的服务器上的某个位置(用户看不到)。将用户选择的答案发送给服务器,并在服务器端检查其正确性。则服务器应该只对浏览器作出响应(即:"correct"/"wrong"),以便用户界面可以前进到下一个问题或给出最终的总分。即使是这样,服务器也不应该信任用户!因此,您应该使用浏览器+后端技术实现一种用户会话,例如:会话Cookie,并检查来自用户的数据是否与数据库中该特定用户的状态匹配(当前问题、正确问题计数、时间戳等)。
在CS50实验室中,这不是现阶段必须解决的话题或问题。但如果您愿意,没有人会阻止您自行探索和实施更强大、更安全的解决方案!

相关文章