事件侦听器多次触发

时间:2021-05-30 08:21:56

标签: javascript dom-events

它是一个测验应用程序,点击重播按钮应该重新开始测验,并且当用户选择问题的答案时使用给定的事件侦听器代码。它在第一次运行时完全正常,但是当测验重新启动时,事件侦听器会触发两次,如果再次单击重播,则用于选择正确选项的事件侦听器会触发三次

let chosen = document.getElementsByClassName("option");
  console.log('options',chosen);
  for (let choosed of chosen) {
    choosed.addEventListener("click", (e) => {
      clearInterval(myVar);
      clearInterval(counterLine);
      console.log("you have choosen");
      next.classList.add("next-show");
      next.classList.remove("next-hide");
      if (questionCount == 10) {
        finish.classList.add("next-show");
        finish.classList.remove("next-hide");
      }
      let choosenOption = e.target.className;
      choosenOption = choosenOption.substr(7, 14);
      let correctOption = arrayOFCorrectAnswers[questionCount - 1];
      if (correctOption.includes(choosenOption)) {
        colorGreen(e.target);
        score++;
      } else {
        colorRed(e.target);
      }
    });
  }

<div class="question-answer">
            <div class="question">
                <h2 id="question">Question Incoming.....</h2>
            </div>
            <div class="options-answers">
                <div class="option" id="option1">option1 </div>
                <div class="option" id="option2">option2</div>
                <div class="option" id="option3">option3</div>
                <div class="option" id="option4">option4</div>
            </div>
        </div>

这是html

1 个答案:

答案 0 :(得分:0)

我试图按照 OP 示例进行操作,但不能很好地理解它。我确实注意到这是一个没有任何表单控件的测验(甚至没有 <button>)。如果您正在与用户交互并需要来自该用户的输入,则您应该使用 <form><input><button> 等。

下面的演示有:

  • init() 包裹了所有变量和函数作为闭包。它传递了 3 个数组。

  • init() 只运行一次。它会将“提交”事件注册到 <form>,并将“点击”事件注册到 <button>。它还运行 spawnQA() 来更改问题的文本和 4 个选项。

  • 选项为 <input type='radio'><label>

const questions = ['Question 1', 'Question 2', 'Question 3', 'Question 4'];
const options = [
  ['1.1', '1.2', '1.3', '1.4'],
  ['2.1', '2.2', '2.3', '2.4'],
  ['3.1', '3.2', '3.3', '3.4'],
  ['4.1', '4.2', '4.3', '4.4']
];
const answers = [1, 0, 3, 2];

const init = (questions, options, answers) => {
  const form = document.forms.QA;
  const io = form.elements;
  const Q = document.getElementById('question');
  const inst = document.querySelector('section');
  const list = document.querySelector('ol');
  const display = document.querySelector('.display');

  let count = parseInt(io.counter.value);
  let score = parseInt(io.correct.value);

  const endQuiz = () => {
    Q.textContent = "Quiz Completed";
    inst.classList.toggle('hide');
    list.classList.toggle('hide');
    io.btn.classList.toggle('hide');
    io.rst.classList.toggle('hide');
    display.textContent = `Score: ${score}`;
    return false;
  };

  const resetQuiz = event => {
    inst.classList.toggle('hide');
    list.classList.toggle('hide');
    io.btn.classList.toggle('hide');
    io.rst.classList.toggle('hide');
    count = 0;
    score = 0;
    spawnQA(questions, options, answers, count);
    form.reset();
  };

  const spawnQA = (questions, options, answers, count) => {
    if (count >= answers.length) {
      endQuiz();
      return false;
    }

    const opts = [...document.querySelectorAll('.option')];

    Q.textContent = `${count+1}. ${questions[count]}`;

    opts.forEach((label, index) => {
      label.textContent = options[count][index];
    });
    return false;
  };

  const nextQuestion = event => {
    event.preventDefault();
    const opts = [...io.options];
    for (let [idx, opt] of opts.entries()) {
      if (opt.checked) {
        score = answers[count] === idx ? ++score : score;
      }
    }
    count++;
    io.counter.value = count;
    io.correct.value = score;
    spawnQA(questions, options, answers, count);
    console.log('score: ' + score);
    console.log('count: ' + count);
  };

  form.onsubmit = nextQuestion;
  io.rst.onclick = resetQuiz;
  spawnQA(questions, options, answers, count);
};

init(questions, options, answers);
.hide {
  display: none
}

ol {
  list-style-type: lower-alpha;
}

button {
  cursor: pointer;
}

input,
label {
  display: inline-block;
  vertical-align: text-top;
}


/* SO Console Display - Right Side Column */

.as-console-wrapper {
  width: 50% !important;
  min-height: 100%;
  margin-left: 50%;
  font-variant: normal;
}

.as-console-row.as-console-row::after {
  content: '';
  padding: 0;
  margin: 0;
  border: 0;
  width: 0;
}
<form id="QA">
  <input id='correct' type='hidden' value='0'>
  <input id='counter' type='hidden' value='0'>
  <fieldset>
    <legend id="question">Question Incoming.....</legend>

    <ol>
      <li>
        <input id='option1' name='options' type='radio'>
        <label for='option1' class='option'>Option 1</label>
      </li>
      <li>
        <input id='option2' name='options' type='radio'>
        <label for='option2' class='option'>Option 2</label>
      </li>
      <li>
        <input id='option3' name='options' type='radio'>
        <label for='option3' class='option'>Option 3</label>
      </li>
      <li>
        <input id='option4' name='options' type='radio'>
        <label for='option4' class='option'>Option 4</label>
      </li>
    </ol>

    <section class='hide'>
      <p class='display'></p>
      <p>Click "Reset" to reset quiz.</p>
    </section>

  </fieldset>
  <button id='btn'>Next</button>
  <button id='rst' class='hide' type='button'>Reset</button>
</form>