首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Javascript事件侦听器在重新启动代码的递归调用后不会触发

Javascript事件侦听器在重新启动代码的递归调用后不会触发
EN

Stack Overflow用户
提问于 2018-09-24 08:17:57
回答 1查看 90关注 0票数 0

问题:

这个内存游戏的代码在我单击restart之前一直有效,它看起来确实可以,但是事件侦听器似乎不再工作了。我有一种预感,这是由于我用来重启游戏的递归调用,但我不明白为什么。有没有人能给我解释一下?

在四处搜索之后,有很多关于事件侦听器没有触发的问题,但它们是由于递归调用以外的原因而发生的。

JSFiddle上的代码

Memory Game on JSFiddle

很抱歉JS仍然这么长,我已经在没有破坏代码的情况下尽可能地删除和简化了。

代码语言:javascript
复制
cards = ['fa-diamond', 'fa-diamond',
'fa-paper-plane','fa-paper-plane',
'fa-anchor','fa-anchor',
'fa-bolt','fa-bolt',
'fa-cube', 'fa-cube',
'fa-bomb','fa-bomb',
'fa-leaf','fa-leaf',
'fa-bicycle','fa-bicycle'];

function initGame() {
    // shuffle the array
    const shuffledCards = shuffle(cards);

    // generates each li
    function generateCardHTML(card) {
      return `<li class="card" data-card=${card}><i class="fa ${card}"></i></li>`
    };

    function createHTML(){
      let deck = "";
      shuffledCards.forEach(function(card) {
        const genHTML = generateCardHTML(card);
        deck += genHTML;
      })
      return deck;
    };
  return createHTML();
};


// Selects the deck div to add all the cards, initialise the game

const gameDeck = document.querySelector('.deck');

gameDeck.innerHTML = initGame();


// Adding event listeners to each card and adding them to openCards array

const cardDeck = document.querySelectorAll('.card');

openCards = [];

cardDeck.forEach(function(card){
  card.addEventListener('click', function(e){
    card.classList.add('open', 'show');

    openingCards(card);
  });
});

// Check if cards match:

function openingCards(targetCard){
  if (targetCard.matches('.open.show')){
    openCards.push(targetCard);
    if (openCards.length == 2) {
      if (openCards[0].dataset.card == openCards[1].dataset.card) {
        openCards[0].classList.add("match");
        openCards[1].classList.add("match");

      };
          setTimeout(function() {
            openCards.forEach(function(card){
              card.classList.remove('open','show');
            })
            openCards = [];
          }, 1000);

    }
  }
};


// Shuffle function from http://stackoverflow.com/a/2450976
function shuffle(array) {
    var currentIndex = array.length, temporaryValue, randomIndex;

    while (currentIndex !== 0) {
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;
        temporaryValue = array[currentIndex];
        array[currentIndex] = array[randomIndex];
        array[randomIndex] = temporaryValue;
    }

    return array;
}

// Code to select restart button and reinitialise the game

const restartBtn = document.querySelector(".fa-repeat");

restartBtn.addEventListener('click',function(e){
  console.log("Restart")
  gameDeck.innerHTML = initGame();
});
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-24 08:40:57

事件侦听器被附加到旧呈现的DOM元素,并且在按下重新启动时不会重新分配给新呈现的元素...

所以你必须在每次重新启动游戏的时候重新连接事件监听器...

建议的解决方案是使用函数包装“附加事件部分代码”,并在每次初始化游戏时调用此函数:

代码语言:javascript
复制
function attachEvents() {
    const cardDeck = document.querySelectorAll('.card');
    cardDeck.forEach(function(card){
        card.addEventListener('click', function(e){
        card.classList.add('open', 'show');

        openingCards(card);
        });
    });
}

JSFiddle

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52471388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档