问题:
这个内存游戏的代码在我单击restart之前一直有效,它看起来确实可以,但是事件侦听器似乎不再工作了。我有一种预感,这是由于我用来重启游戏的递归调用,但我不明白为什么。有没有人能给我解释一下?
在四处搜索之后,有很多关于事件侦听器没有触发的问题,但它们是由于递归调用以外的原因而发生的。
JSFiddle上的代码
很抱歉JS仍然这么长,我已经在没有破坏代码的情况下尽可能地删除和简化了。
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();
});
发布于 2018-09-24 08:40:57
事件侦听器被附加到旧呈现的DOM元素,并且在按下重新启动时不会重新分配给新呈现的元素...
所以你必须在每次重新启动游戏的时候重新连接事件监听器...
建议的解决方案是使用函数包装“附加事件部分代码”,并在每次初始化游戏时调用此函数:
function attachEvents() {
const cardDeck = document.querySelectorAll('.card');
cardDeck.forEach(function(card){
card.addEventListener('click', function(e){
card.classList.add('open', 'show');
openingCards(card);
});
});
}
https://stackoverflow.com/questions/52471388
复制相似问题