setInterval函数console.log中的click事件上的double事件(有时是double事件)

时间:2018-06-21 19:02:43

标签: javascript jquery

第一次问一个问题,请多多包涵。非常感谢您的帮助!

我的代码如下所示。我正在尝试创建一个Trivia游戏。

我的问题是,当我运行代码时,有时每次单击都会注册两个或多个单击事件。我做了一些研究,我认为对此的解释是因为我在同一个div区域绑定了一个以上的事件侦听器,并且该事件侦听器计数两次​​,并且附加的事件侦听器数量增加了三倍。但是我无法弄清楚这发生的地点和原因。

//  To set global variables and objects. 
var game = [
  [
    "How did Daenarys Targaryen eventually hatch her dragon eggs?", ["1. In a lightning storm", "2. In a funeral pyre", "3. In a fireplace", "4. In a frozen cave"],
    "2. In a funeral pyre",
    "assets/images/q1",
  ],
  [
    "The phrase 'Valar Morghulis' or 'all men must die' is usually responded with:", ["1. Valar Dohaeris or 'all men must serve'", "2. Valar Rohnas or 'all men must live'", "3. Valar GoGo or 'all men must dance'", "4. Valar Morghulis or 'all men must fight'"],
    "1. Valar Dohaeris or 'all men must serve'",
    "assets/images/q2",
  ],
  [
    "What is the only thing that can put out volatile Wildfire?", ["1. Sand", "2. Water", "3. Dragon's blood", "4. Sunlight"],
    "1. Sand",
    "assets/images/q3",
  ],
  [
    "Besides dragonglass, what is the only other substance capable of defeating White Walkers?", ["1. Weirwood", "2. Wildfire", "3. Valyrian Steel", "4. Magma"],
    "3. Valyrian Steel",
    "assets/images/q4",
  ],
  [
    "Arya's punishment for stealing from the Many-Face God is:", ["1. Death", "2. Memory Loss", "3. Blindness", "4. A Broken Arm"],
    "3. Blindness",
    "assets/images/q5",
  ],
  [
    "What was the name of Ned Stark's greatsword?", ["1. Oathkeeper", "2. Deathbringer", "3. Northguard", "4. Ice"],
    "4. Ice",
    "assets/images/q6",
  ],
  [
    "Who shoots the flaming arrow that subsequently destroy's Stannis' fleet in Blackwater Bay?", ["1. Tyrion Lannister", "2. King Joffrey", "3. Jaime Lannister", "4. Bronn"],
    "4. Bronn",
    "assets/images/q7",
  ],
  [
    "Prince Oberyn Martell is nicknamed the 'Red Viper' because of his combat and:", ["1. Pride in drawing blood first", "2. Knowledge of poisons", "3. Nighttime attacks", "4. Ruby-colored armor"],
    "2. Knowledge of poisons",
    "assets/images/q8",
  ],
  [
    "The Night King was created using a dagger made of:", ["1. Blue Ice", "2. Valyrian Steel", "3. Dragonglass", "4. Obsidian"],
    "3. Dragonglass",
    "assets/images/q9",
  ],
  [
    "How many arrows does Ramsay Bolton let loose at Rickon Stark?", ["1. Three", "2. Four", "3. Five", "4. Six"],
    "2. Four",
    "assets/images/q10",
  ],
]

var b = $.extend(true, [], game);
var qCountdown;
var ans;
var counter;

$(document).ready(function() {
  var correct = 0;
  var incorrect = 0;
  var unanswered = 0;
  var button = $(".optBtn");
  var start = $("#startBtn");
  var question = $("#question");
  var answer = $("#answer");
  var countdown = $("#timeout");
  var options;
  var qCounter = 0;

  // To hide certain HTML elements before the game starts.
  button.hide();

  // To Initiate the newGame function.
  function newGame() {
    nextQuestion();
  }

  // To initiate the nextQuestion function. 
  function nextQuestion() {
    countdown.show();
    question.show();
    button.show();
    start.hide();
    answer.empty();

    // Set the ending condition to display the results page. 
    if (qCounter !== 10) {
      test()
      // Set a condition and display for if the counter reaches 0.
      counter = 10;
      qCountdown = setInterval(function() {
        counter--;
        countdown.text(counter);
        if (counter === 0) {
          b.shift();
          clearInterval(qCountdown);
          countdown.hide();
          button.hide();
          console.log(qCounter + "TimeUp");
          console.log(b.length + "TimeUp");
          answer.text("The correct answer is " + ans + ".");
          $("#unanswered").text("Uh oh, you did not answer the question in time.");
          unanswered++;
          qCounter++;
          window.setTimeout(nextQuestion, 2000);
          return;
        }
      }, 1000);
    } else {
      b = $.extend(true, [], game);
      countdown.hide();
      question.hide();
      button.hide();
      start.show();
      clearInterval(qCountdown);
      answer.text("You guessed " + correct + " questions correctly, and " + incorrect + " questions incorrectly.");
      var unans = $("#unanswered");
      unans.text("You did not answer " + unanswered + " questions.");
      return;
    };
    var quest = question.text(b[0][0]);
    ans = b[0][2];
    var img;
    // console.log();

    // To assign each option button with one of the four options.
    for (i = 0; i < 4; i++) {
      btns = {
        generator: function() {
          return b[0][1][i];
        }
      };

      button.each(function() {
        $(this).text(btns.generator());
        $(this).attr("data-value", btns.generator());
        i++;
      });
    }
  };

  function test() {
    // On-click function for the buttons to register a correct or incorrect guess. 
    button.on("click", function() {
      button.hide();
      console.log("You clicked a button once");

      options = $(this).attr("data-value");
      countdown.hide();
      question.hide();
      clearInterval(qCountdown);
      window.setTimeout(nextQuestion, 2000);
      qCounter++;
      b.shift();
      if (options === ans) {
        console.log(qCounter + "Click");
        console.log(b.length + "Click");
        answer.text("You guessed correctly, the answer is " + ans);
        correct++;
        button.off("click");
        return;
      } else {
        console.log(counter + "Clack");
        console.log(b.length + "Clack");
        answer.text("You guessed incorrectly, the answer is " + ans);
        incorrect++;
        button.off("click");
      };
    });

  }

  $("#startBtn").on("click", function() {

    // game = $.extend(true, [], b);
    newGame();
  })
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

1 个答案:

答案 0 :(得分:0)

我认为问题是,当时间用完时,您正在调用nextQuestion(),后者会调用test(),这会将.on('click')分配给类.optBtn的每个按钮。但是,只有选择答案后,您才能关闭click事件。

因此,如果时间用完并且没有点击,则将新的点击事件添加到每个按钮,这样您最终将在按钮上附加多个点击事件。

尝试将button.off("click");语句从代码中的当前位置移至nextQuestion()test()顶部附近的单个调用。因此,每次计时器用尽时,它都会清除点击事件,并将其附加。

也许有更好的方法,这是一个很长的代码段,但是请尝试该建议。