【问题标题】:Onclick event not working as expected. Any idea why?Onclick 事件未按预期工作。知道为什么吗?
【发布时间】:2021-03-16 16:13:36
【问题描述】:

我正在开发一个 非常 简单的 javascript 测验项目,它有一个分数和一个开始按钮,当它被点击时会生成问题。我通过添加一个 onclick 事件侦听器开始在 JS 代码中工作,但它没有按预期工作。这是应该可以工作但不起作用的代码 sn-p,有几个 cmets。请记住,我对 Javascript 非常缺乏经验,所以我可能误用了一些 JS 方法。

    function rng() {
 return Math.floor(Math.random * 10)
}
let stbt = document.getElementById("start")
stbt.addEventListener("click", function() { 
    stbt.remove //should remove the start button when it gets clicked.
    let q = document.createElement("p") //created an html paragraph.
    switch(rng()) {
        case 1:
         let qc = document.createTextNode("What is the capital of Chile?") 
         q.appendChild(qc) /*this should theoretically insert text into the html paragraph that gets created when the start button gets clicked,
         the switch statement that is switching the simple rng function should make it so that questions get generated randomly.*/
         break;
        case 2: 
         let qc = document.createTextNode("What is the highest mountain in Britain?")
         q.appendChild(qc)
         break;
        case 3: 
         let qc = document.createTextNode("What is the smallest country in the world?")
         q.appendChild(qc)
         break;
        case 4: 
         let qc = document.createTextNode("Alberta is a province of which country?")
         q.appendChild(qc)
         break;
        case 5: 
         let qc = document.createTextNode("How many countries still have the shilling as currency?")
         q.appendChild(qc)
         break;
        case 6: 
         let qc = document.createTextNode("Which is the only vowel not used as the first letter in a US State?")
         q.appendChild(qc)
         break;
        case 7: 
         let qc = document.createTextNode("What is the largest country in the world?")
         q.appendChild(qc)
         break;
        case 8: 
         let qc = document.createTextNode("Where would you find the River Thames?")
         q.appendChild(qc)
         break;
        case 9: 
         let qc = document.createTextNode("What is the hottest continent on Earth?")
         q.appendChild(qc)
         break;
        case 0: 
         let qc = document.createTextNode("What is the longest river in the world?")
         q.appendChild(qc)
         break;
    }
})

【问题讨论】:

  • stbt.remove() q 附加到任何内容,这就是它不显示的原因。
  • 您还缺少Math.random() 上的括号,并且您不能多次声明qc,您需要在switch 之外声明一次,然后在其中分配它相关的case。正如异端猴子所说,你永远不会将<p> 元素附加到任何东西上。
  • 你能简化一下吗?也许只有一个案例?

标签: javascript onclick switch-statement


【解决方案1】:

这不是监听器的错误,而是一些小错误导致您的代码无法工作。

  • 你不是calling有两个函数:Math.random应该是Math.random()stbt.remove应该是stbt.remove()

  • 由于您编写switch 的方式,您的qc 变量的范围是所有case 语句,因此您不能再次声明它。您可以通过在switch 之外声明它并在case 语句中分配它来解决此问题,或者使用大括号将变量范围限定为每个case

let qc; //<--- declare qc;
  switch (rng()) {
    case 1:
      qc = document.createTextNode("What is the capital of Chile?")
      ...
      break;
    case 2:
      qc = document.createTextNode("What is the highest mountain in Britain?")
      ...

  switch (rng()) { 
    case 1: { //<--- braces to scope variable declaration
      let qc = document.createTextNode("What is the capital of Chile?")
      ...
      break;
    }
    case 2: {
      let qc = document.createTextNode("What is the highest mountain in Britain?")
      ...
      break;
    }
    case 3: {
      ...
  • 最后,永远不要将&lt;p&gt; 元素附加到DOM。您需要查询要附加到的元素,或者如下例所示,直接附加到document.body

switch 语句往往非常冗长,因此它有助于尽可能避免重复。除了在每个 case 中附加新文本节点之外,您还可以将其移动到 switch 之后并只调用一次。

stbt.addEventListener("click", function () {
  ...
  let qc;
  switch (rng()) {
    case 1: 
      ...
  }
  // Avoid duplication by appending once at the end
  q.appendChild(qc)
  document.body.appendChild(q) //<--- append <p> to DOM
});

function rng() {
  return Math.floor(Math.random() * 10); //<--- parentheses needed to call function;
}

const stbt = document.getElementById("start");

stbt.addEventListener("click", function () {
  stbt.remove(); //<--- parentheses needed to call function;
  let q = document.createElement("p");
  let qc; //<--- declare qc;
  switch (rng()) {
    case 1: {
      let qc = document.createTextNode("What is the capital of Chile?")
      break;
      }
    case 2:
      qc = document.createTextNode("What is the highest mountain in Britain?")
      break;
    case 3:
      qc = document.createTextNode("What is the smallest country in the world?")
      break;
    case 4:
      qc = document.createTextNode("Alberta is a province of which country?")
      break;
    case 5:
      qc = document.createTextNode("How many countries still have the shilling as currency?")
      q.appendChild(qc)
      break;
    case 6:
      qc = document.createTextNode("Which is the only vowel not used as the first letter in a US State?")
      break;
    case 7:
      qc = document.createTextNode("What is the largest country in the world?")
      break;
    case 8:
      qc = document.createTextNode("Where would you find the River Thames?")
      q.appendChild(qc)
      break;
    case 9:
      qc = document.createTextNode("What is the hottest continent on Earth?")
      break;
    case 0:
      qc = document.createTextNode("What is the longest river in the world?")
      break;
  }
  // Avoid duplication by appending once at the end
  q.appendChild(qc)
  document.body.appendChild(q) //<--- append <p> to the DOM
});
&lt;button type="button" id='start'&gt;Start&lt;/button&gt;

使其更通用

使用switch 可以非常清楚地显示正在发生的事情,但它确实会导致大量重复。如果你想添加一个问题,你需要添加一个全新的case 语句以及更改rng() 函数中的常量。为避免这种情况,您可能需要考虑可能服务于您的目的的其他结构。

这是一个使用数组存储问题的示例,该问题使用来自rng() 的返回值通过索引访问(已更改为接受max 值)。使用这种结构,添加问题只是添加到数组中的问题,其余的自行处理。

function rng(max) {
  return Math.floor(Math.random() * max)
}

const questions = [
  "What is the capital of Chile?",
  "What is the highest mountain in Britain?",
  "What is the smallest country in the world?",
  "Alberta is a province of which country?",
  "How many countries still have the shilling as currency?",
  "Which is the only vowel not used as the first letter in a US State?",
  "What is the largest country in the world?",
  "Where would you find the River Thames?",
  "What is the hottest continent on Earth?",
  "What is the longest river in the world?",
]

const stbt = document.getElementById("start")
const div = document.getElementById("questions")

stbt.addEventListener("click", function () {
  // pass the length of the questions array as the max value for the rng()
  const questionIndex = rng(questions.length);
  const question = questions[questionIndex];

  stbt.remove();

  const q = document.createElement("p");
  const qc = document.createTextNode(question)

  q.appendChild(qc)
  div.appendChild(q)
});
<button type="button" id='start'>Start</button>
<div id='questions'></div>

【讨论】:

  • Tysm 寻求帮助。奇怪的是,stackoverflow 代码 sn-p 运行良好,但我的 vsc 项目并没有消除按钮并在 onclick 事件上显示问题。我重新检查了 ids 和可能的语法错误,但我似乎找不到任何错误,这可能是我的 html/css 代码中的一些东西,虽然我没有在那里写很多,所以我强烈怀疑它:/
  • 你在哪里运行它?
  • 我正在从 VSC 运行和调试它
  • 如果不了解您的代码以及如何从 VSC 提供代码,很难说。您可能想发布另一个问题。如果这个回答对你有帮助,请采纳。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-04
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多