gpt4 book ai didi

递归调用重新启动代码后,Javascript 事件监听器不会触发

转载 作者:行者123 更新时间:2023-12-03 01:04:30 24 4
gpt4 key购买 nike

问题:

这个内存游戏的代码一直有效,直到我单击“重新启动”为止,它似乎确实如此,但随后事件监听器似乎不再工作。我有预感这是由于我用来重新启动游戏的递归调用造成的,但我不明白为什么。有人可以向我解释一下吗?

经过搜索后,有很多关于事件监听器未触发的问题,但它们发生的原因不是递归调用。

JSFiddle 上的代码

Memory Game on 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();
});

最佳答案

事件监听器附加到旧渲染的 DOM 元素,并且在按重新启动时不会重新分配给新渲染的元素...
因此,每次重新启动游戏时,您都必须重新附加事件监听器...
建议的解决方案是包装“用函数附加代码的事件部分”并在每次启动游戏时调用此函数:

function attachEvents() {
const cardDeck = document.querySelectorAll('.card');
cardDeck.forEach(function(card){
card.addEventListener('click', function(e){
card.classList.add('open', 'show');

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

JSFiddle

关于递归调用重新启动代码后,Javascript 事件监听器不会触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52471388/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com