【问题标题】:removeEventListener only removing single instanceremoveEventListener 仅删除单个实例
【发布时间】:2020-05-25 00:44:03
【问题描述】:

我遇到的问题是,当我尝试从按钮中删除事件时,它似乎只是删除了单按钮的事件,即使我已经循环访问了按钮并删除了事件。

谢谢。

function ChangeQuestions() {
    let currentQuestion = getQuestion(); //another function to get the question from an array - returns an object with questions, answers and correctAnswer
    const correctAnswer = currentQuestion.correct;
    console.log(currentQuestion);
    if (questionsArray.length === 0) {
        //If the array is empty push the questions again
        questionsArray.push(firstQuestion, secondQuestion, thirdQuestion);
    }
    document.querySelector('.question-header').textContent = currentQuestion.questions;
    for (let i = 1; i < 4; i++) {
        document.querySelector('.btn-Ans-' + i).textContent = currentQuestion.answers[i - 1];
        document.querySelector('.btn-Ans-' + i).addEventListener('click', function checkAns(e) {
            if (e.target.innerHTML === correctAnswer) {
                score++;
                console.log(score);
                removeEvent('click', checkAns);
                ChangeQuestions();
            } else {

                console.log(score);
                removeEvent('click', checkAns);
                ChangeQuestions();
            }
        });
    }
}


function removeEvent(event, func) {
    for (let i = 1; i < 4; i++) {
        document.querySelector('.btn-Ans-' + i).removeEventListener(event, func);
    }
}

【问题讨论】:

    标签: javascript removeeventlistener


    【解决方案1】:

    for (let i = 1; i < 4; i++) {
      document.querySelector('.btn-Ans-' + i).addEventListener('click', function checkAns(e) {
    

    一个新的checkAns 函数在循环的每次迭代中创建,并且removeEventListener 必须传递与调用addEventListener 完全相同的函数 .由于不同的循环迭代将不同的函数传递到它们各自的addEventListener 调用中,removeEvent 函数似乎只影响被点击的元素,而不影响其余元素。

    这是一个更简单的例子:

    const fns = [];
    for (let i = 0; i < 2; i++) {
      const foo = () => console.log('foo');
      fns.push(foo);
      window.addEventListener('click', foo);
    }
    
    // Not the same function:
    console.log(fns[0] === fns[1]);

    我只向容器添加一个 single 侦听器,并使用事件委托来检查单击了哪个元素:

    btnContainer.addEventListener('click', function handler(e) {
      if (!e.target.matches('[class^="btn-Ans"]')) {
        return;
      }
      btnContainer.removeEventListener('click', handler);
      if (e.target.innerHTML === correctAnswer) {
        score++;
      }
      console.log(score);
      ChangeQuestions();
    });
    

    其中btnContainer 是您的btn-Ans-s 的容器。

    【讨论】:

    • 您好,我了解您的方法,但 .matches 行是如何工作的?我不太清楚如何实现它。
    • 这就是事件委托——给容器添加一个事件监听器,当事件在容器上触发时,查看目标元素是否是你想要检测点击的子元素。这就是matches 所做的。如果匹配,则继续执行其余的函数。
    猜你喜欢
    • 1970-01-01
    • 2023-01-25
    • 1970-01-01
    • 2015-05-15
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    • 2023-03-29
    • 2012-08-11
    相关资源
    最近更新 更多