Javascript函数多次触发

时间:2020-07-06 16:49:45

标签: javascript

我正在尝试使用Javascript函数编写琐事测验。每个问题都引用了一些全局定义的功能。 “正确”和“错误”应该为得分加分。但是,在我完成测验时,它正在侦听上一个问题功能的对与错功能。我没有帮助就尝试了许多修复程序。我和我的导师在上面挠了几个小时,所以现在我发现自己在这里。

我们都认为,如果事件监听器用大括号括起来,则它们不应监听其他功能的点击...

任何建议将不胜感激!

注意:第三和第四个问题函数使用的是我对第一个和第二个问题尝试过的原始格式。

var timeEl = document.querySelector(".time");
var mainEl = document.getElementById("main");

var A = document.getElementById("A");
var B = document.getElementById("B");
var C = document.getElementById("C");
var D = document.getElementById("D");

var textA = document.querySelector(".textA");
var textB = document.querySelector(".textB");
var textC = document.querySelector(".textC");
var textD = document.querySelector(".textD");

var points = 0;

var secondsLeft = 60;

function setTime() {
  var timerInterval = setInterval(function() {
    secondsLeft--;
    timeEl.textContent = "Time: " + secondsLeft;

    if (secondsLeft === 0) {
      clearInterval(timerInterval);
      changePage();
    }

  }, 1000);
}

function changePage() {
  window.location.href = "./ending.html";
}

function wrong() {
  var anResult = document.getElementById("answer-result");
  anResult.textContent = "Wrong! -10 Points! :("
  points = points - 10;
  console.log(points)
}

function right() {
  var anResult = document.getElementById("answer-result");
  anResult.textContent = "Right! +10 Points! :)"
  points = points + 10;
  console.log(points)
}

setTime();
firstQuestion();

function q1CorrectClick() {
  right();
  secondQuestion();
  console.log("A")
}

function q1WrongClick() {
  wrong();
  secondQuestion();
}

function q2CorrectClick() {
  right();
  thirdQuestion();
}

function q2WrongClick() {
  wrong();
  thirdQuestion();
}

function firstQuestion() {
  var question = document.getElementById("question");
  A.addEventListener("click", q1WrongClick)
  // wrong()
  // secondQuestion()
  // console.log("A")
  // // A.removeEventListener();
  // };
  B.addEventListener("click", q1WrongClick)
  //   wrong()
  //   secondQuestion()
  //   console.log("B") this function will fire in the subsequent questionFunctions 
  //   // B.removeEventListener();
  // });
  C.addEventListener("click", q1WrongClick)
  //   wrong()
  //   secondQuestion()
  //   console.log("C")
  //   // C.removeEventListener();
  // });
  D.addEventListener("click", q1CorrectClick)
  //   right()
  //   secondQuestion()
  //   console.log("D")
  //   // D.removeEventListener();
  // });

  question.textContent = "What is the best selling car of all time?";

  textA.textContent = "Toyota Camry";
  textB.textContent = "Ford F-150";
  textC.textContent = "Honda Civic";
  textD.textContent = "Toyota Corolla";
  // the right answer! 
}

function secondQuestion() {
  var question = document.getElementById("question");
  A.addEventListener("click", q2WrongClick)
  //   wrong()
  //   thirdQuestion()
  // });
  B.addEventListener("click", q2CorrectClick)
  //   right()
  //   thirdQuestion()
  // });
  C.addEventListener("click", q2WrongClick)
  //   wrong()
  //   thirdQuestion()
  // });
  D.addEventListener("click", q2WrongClick)
  //   wrong()
  //   thirdQuestion()
  // });
  question.textContent = "First introduced in 1974, which iconic hatchback still remains popular today?";

  textA.textContent = "Ford Mustang";
  textB.textContent = "Volkswagen Golf";
  textC.textContent = "Toyota Celica";
  textD.textContent = "Fiat 500";

  // document.getElementById("quiz-body").removeEventListener("mouseover", firstQuestion); this didn't work. console.log functions still working from previous function.
}

function thirdQuestion() {
  var question = document.getElementById("question");
  A.addEventListener("click", function() {
    wrong()
    fourthQuestion()
  });
  B.addEventListener("click", function() {
    wrong()
    fourthQuestion()
  });
  C.addEventListener("click", function() {
    right()
    fourthQuestion()
  });
  D.addEventListener("click", function() {
    wrong()
    fourthQuestion()
  });
  question.textContent = "What is the world's fastest production car as of July 2020?";

  textA.textContent = "Koenigsegg Agera RS";
  textB.textContent = "Hennessy Venom GT";
  textC.textContent = "Buggatti Chiron Super Sport";
  textD.textContent = "Lamborghini Aventador";
}

function fourthQuestion() {
  var question = document.getElementById("question");
  A.addEventListener("click", function() {
    right()
    fifthQuestion()
  });
  B.addEventListener("click", function() {
    wrong()
    fifthQuestion()
  });
  C.addEventListener("click", function() {
    wrong()
    fifthQuestion()
  });
  D.addEventListener("click", function() {
    wrong()
    fifthQuestion()
  });
  question.textContent = "What 70s car is known for its suicide doors and convertible top?";

  textA.textContent = "Lincoln Continental";
  textB.textContent = "Buick Rivera";
  textC.textContent = "Ford Thunderbird";
  textD.textContent = "Oldsmobile Toronado";
}
<div class="time"></div>
<div id="main">
  <div id="question"></div>
  <div>
    <input id="A" type="radio" name="choice" />
    <label class="textA"></label>
  </div>
  <div>
    <input id="B" type="radio" name="choice" />
    <label class="textB"></label>
  </div>
  <div>
    <input id="C" type="radio" name="choice" />
    <label class="textC"></label>
  </div>
  <div>
    <input id="D" type="radio" name="choice" />
    <label class="textD"></label>
  </div>
  <div id="answer-result"></div>
</div>

1 个答案:

答案 0 :(得分:0)

您永远不会从上一个问题中删除点击处理程序,而只会添加新的处理程序。

我建议采用另一种方法。一种根本不需要更改点击处理程序的地方。这个想法是,您不会将问题和答案编码为 code ,而是编码为 data 。这样,您还可以避免代码重复。

因此,首先定义一个数据结构,其中包含所有问题,答案和正确答案。例如:

var questions = [{ 
    question: "What is the best selling car of all time?", 
    answers: ["Toyota Camry", "Ford F-150", "Honda Civic", "Toyota Corolla"],
    correct: 3 // note: first answer has number 0
}, { 
    question: "First introduced in 1974, which iconic hatchback still remains popular today?",
    answers: ["Ford Mustang", "Volkswagen Golf", "Toyota Celica", "Fiat 500"],
    correct: 1
}, {
    question: "What is the world's fastest production car as of July 2020?",
    answers: ["Koenigsegg Agera RS", "Hennessy Venom GT", "Buggatti Chiron Super Sport", "Lamborghini Aventador"],
    correct: 2
}, { 
    question: "What 70s car is known for its suicide doors and convertible top?",
    answers: ["Lincoln Continental", "Buick Rivera", "Ford Thunderbird", "Oldsmobile Toronado"],
    correct: 0
}];

现在唯一需要从一个问题转到下一个问题的是...该数组中的索引:它应该从0移到1,... 2,最后是3。

有关该问题的所有您需要了解的其他信息都可以在该索引中找到。

我还建议您在显示下一个问题之前,让用户有一段时间查看其答案的结果。在新问题尚未回答的情况下,看到下面带有“更正”消息的新问题可能会造成混淆。

这是一个只有一个单击处理程序的实现:一个处理所有四个按钮的操作。

var timeEl = document.querySelector(".time");

var question = document.getElementById("question");
var answerButtons = Array.from(document.querySelectorAll(".answer"));
var answerTexts = document.querySelectorAll(".text");
var anResult = document.getElementById("answer-result");
var score = document.getElementById("score");

var points = 0;
var secondsLeft = 60;

function setTime() {
  var timerInterval = setInterval(function() {
    secondsLeft--;
    timeEl.textContent = secondsLeft;

    if(secondsLeft === 0) {
      clearInterval(timerInterval);
      changePage();
    }
  }, 1000);
}

function changePage() {
  // Commented out for this demo only
  // window.location.href = "./ending.html";
}

function displayResult(isCorrect) {
    if (isCorrect) {
        points = points + 10;
        anResult.textContent = "Right! +10 Points! :)"
    } else {
        points = points - 10;
        anResult.textContent = "Wrong! -10 Points! :("
    }
    score.textContent = points
    enableButtons(false); // Prevent that user keeps clicking buttons
}

function enableButtons(on) {
    for (let button of answerButtons) {
        button.disabled = !on;
    }
}

setTime();

var questions = [{ 
    question: "What is the best selling car of all time?", 
    answers: ["Toyota Camry", "Ford F-150", "Honda Civic", "Toyota Corolla"],
    correct: 3 // note: first answer has number 0
}, { 
    question: "First introduced in 1974, which iconic hatchback still remains popular today?",
    answers: ["Ford Mustang", "Volkswagen Golf", "Toyota Celica", "Fiat 500"],
    correct: 1
}, {
    question: "What is the world's fastest production car as of July 2020?",
    answers: ["Koenigsegg Agera RS", "Hennessy Venom GT", "Buggatti Chiron Super Sport", "Lamborghini Aventador"],
    correct: 2
}, { 
    question: "What 70s car is known for its suicide doors and convertible top?",
    answers: ["Lincoln Continental", "Buick Rivera", "Ford Thunderbird", "Oldsmobile Toronado"],
    correct: 0
}];

var currentQuestion = 0;
displayQuestion();

document.addEventListener("click", function (e) { // One click handler for all four buttons
    let buttonNum = answerButtons.indexOf(e.target);
    if (buttonNum < 0) return; // This was not a click event on an answer button
    displayResult(buttonNum === questions[currentQuestion].correct);
    setTimeout(function () { // allow some time for the user to see the result
        currentQuestion++;
        if (currentQuestion >= questions.length) return changePage(); // Or whatever is suitable
        displayQuestion();
    }, 2000); 
});

function displayQuestion() {
    question.textContent = questions[currentQuestion].question;
    questions[currentQuestion].answers.forEach(function (answer, i) {
        answerTexts[i].textContent = answer;
    });
    enableButtons(true);
    anResult.textContent = ""
}
Time: <span class="time">60</span><br>
Score: <span id="score">0</span><br>
<div id="question"></div>
<button class="answer">A</button> <span class="text"></span><br>
<button class="answer">B</button> <span class="text"></span><br>
<button class="answer">C</button> <span class="text"></span><br>
<button class="answer">D</button> <span class="text"></span><br>
<div id="answer-result"></div>