在记忆游戏中点击卡片不会翻转它
Posted
技术标签:
【中文标题】在记忆游戏中点击卡片不会翻转它【英文标题】:Clicking card in memory game doesn't flip it over 【发布时间】:2018-05-30 08:17:11 【问题描述】:我正在尝试制作一个记忆游戏,并且正在努力让卡片在被点击时翻转。我希望以下 for 循环在单击卡片(对应于每个 li
类 card
的项目)时调用函数 displayCard
,该函数切换类 show
和 open
(将卡片设置为可见 [显示图标] 并更改背景颜色)。有什么建议么?
CodePen
for循环:
for (let i = 0; i < cards.length; i++)
card = cards[i];
card.addEventListener('click', displayCard);
card.addEventListener('click', cardOpen);
card.addEventListener('click', congratulations);
displayCard
函数:
let displayCard = function()
this.classList.toggle('open');
this.classList.toggle('show');
this.classList.toggle('disabled');
;
show
和 open
类的 CSS:
.card-deck .card.open
/* transform: rotateY(0); */
background: #02b3e4;
cursor: default;
animation-name: flipInY;
-webkit-backface-visibility: visible !important;
backface-visibility: visible !important;
animation-duration: .75s;
.card-deck .card.show
font-size: 33px;
.show
visibility: visible !important;
opacity: 100 !important;
【问题讨论】:
控制台中显示您的 Codepen 中有错误。当你摆脱这些 - 我看到一些翻转。 只要解决错误,代码就可以工作了:) 【参考方案1】:您的代码中有两个错误需要修复,然后发生翻转:
在startGame
函数中,deck.appendChild
不是函数。甲板用 document.getElementsByClassName('card-deck') 初始化。并且 document.getElementsByClassName 返回一个数组。您需要选择此数组的第一个索引。
在startGame
函数中,interval
未定义。在声明 interval
变量之前调用您的函数。使用 var
关键字声明它的 interval
变量声明向上移动以“保留”标识符。
let card = document.getElementsByClassName('card');
// Spread operator (new in ES6) allows iterable to expand where 0+ arguments are expected
let cards = [...card];
let deck = document.getElementsByClassName('card-deck')[0];
let moves = 0;
let counter = document.querySelector('.moves');
let stars = document.querySelectorAll('.fa-star');
let matchingCard = document.getElementsByClassName('matching');
let starsList = document.querySelectorAll('.stars li');
let closeIcon = document.querySelector('.close');
let modal = document.getElementsByClassName('main-modal');
let openedCards = [];
// Game timer
let second = 0, minute = 0, hour = 0;
let timer = document.querySelector('.timer');
let interval;
// Shuffle function from http://***.com/a/2450976
function shuffle(array)
let 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;
// Shuffles cards upon page load
document.body.onload = startGame();
function startGame()
// Shuffles deck
cards = shuffle(cards);
// Removes any existing classes from each card
for (let i = 0; i < cards.length; i++)
deck.innerhtml = '';
[].forEach.call(cards, function(item)
deck.appendChild(item);
);
cards[i].classList.remove('show', 'open', 'matching', 'disabled');
// Resets number of moves
moves = 0;
counter.innerHTML = moves;
// Resets star rating
for (let i = 0; i < stars.length; i++)
stars[i].style.color = '#ffd700';
stars[i].style.visibility = 'visible';
// Resets timer
let second = 0;
let minute = 0;
let hour = 0;
let timer = document.querySelector('.timer');
timer.innerHTML = '0 mins 0 secs';
if (typeof interval != "undefined")
sclearInterval(interval);
// Toggles open and show classes to display cards
let displayCard = function()
this.classList.toggle('open');
this.classList.toggle('show');
this.classList.toggle('disabled');
;
// Adds opened cards to openedCards list and checks if cards are a match or not
function cardOpen()
openedCards.push(this);
let len = openedCards.length;
if (len === 2)
moveCounter();
if (openedCards[0].type === openedCards[1].type)
matching();
else
notMatching();
// When cards match
function matching()
openedCards[0].classList.add('matching', 'disabled');
openedCards[1].classList.add('matching', 'disabled');
openedCards[0].classList.remove('show', 'open');
openedCards[1].classList.remove('show', 'open');
openedCards = [];
// When cards don't match
function notMatching()
openedCards[0].classList.add('not-matching');
openedCards[1].classList.add('not-matching');
disable();
setTimeout(function()
openedCards[0].classList.remove('show', 'open', 'not-matching');
openedCards[1].classList.remove('show', 'open', 'not-matching');
enable();
openedCards = [];
, 1100);
// Disables cards temporarily
function disable()
Array.prototype.filter.call(cards, function(card)
card.classList.add('disabled');
);
// Enables cards, disables matching cards
function enable()
Array.prototype.filter.call(cards, function(card)
card.classList.remove('disabled');
for (let i = 0; i < matchingCard.length; i++)
matchingCard[i].classList.add('disabled');
);
// Counts player's moves
function moveCounter()
moves++;
counter.innerHTML = moves;
// Starts timer on first click
if (moves == 1)
second = 0;
minute = 0;
hour = 0;
startTimer();
// Sets star rating based on number of moves
if (moves > 8 && moves < 12)
for (i = 0; i < 3; i++)
if (i > 1)
stars[i].style.visibility = 'collapse';
else if (moves > 13)
for (i = 0; i < 3; i++)
if (i > 0)
stars[i].style.visibility = 'collapse';
function startTimer()
interval = setInterval(function()
timer.innerHTML = minute + 'mins ' + second + 'secs';
second++;
if (second == 60)
minute++;
second = 0;
if (minute == 60)
hour++;
minute = 0;
, 1000);
// Congratulates player when all cards match and shows modal, moves, time and rating
function congratulations()
if (matchingCard.length == 16)
clearInterval(interval);
let finalTime = timer.innerHTML;
// Shows congratulations modal
modal.classList.add('show');
let starRating = document.querySelector('.stars').innerHTML;
// Shows move, time, and rating on modal
document.getElementsByClassName('final-move').innerHTML = moves;
document.getElementsByClassName('star-rating').innerHTML = starRating;
document.getElementsByClassName('total-time').innerHTML = finalTime;
closeModal();
// Closes modal upon clicking its close icon
function closeModal()
closeIcon.addEventListener('click', function(e)
modal.classList.remove('show');
startGame();
);
function reset()
modal.classList.remove('show');
startGame();
// Adds event listeners to each card
for (let i = 0; i < cards.length; i++)
card = cards[i];
card.addEventListener('click', displayCard);
card.addEventListener('click', cardOpen);
card.addEventListener('click', congratulations);
html
box-sizing: border-box;
*,
*::before,
*::after
box-sizing: inherit;
html,
body
width: 100%;
height: 100%;
margin: 0;
padding: 0;
body
background: #ffffff;
font-family: 'Permanent Marker', cursive;
font-size: 16px;
.container
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
h1
font-family: 'Gloria Hallelujah', cursive;
/* DECK OF CARDS */
.card-deck
width: 85%;
background: #716F71;
padding: 1rem;
border-radius: 4px;
box-shadow: 8px 9px 26px 0 rgba(46, 61, 73, 0.5);
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: center;
margin: 0 0 3em;
.card-deck .card
height: 3.7rem;
width: 3.7rem;
margin: 0.2rem 0.2rem;
background: #141214;;
font-size: 0;
color: #ffffff;
border-radius: 5px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 5px 2px 20px 0 rgba(46, 61, 73, 0.5);
.card-deck .card.open
/* transform: rotateY(0); */
background: #02b3e4;
cursor: default;
animation-name: flipInY;
-webkit-backface-visibility: visible !important;
backface-visibility: visible !important;
animation-duration: .75s;
.card-deck .card.show
font-size: 33px;
.show
visibility: visible !important;
opacity: 100 !important;
.card-deck .card.matching
cursor: default;
background: #E5F720;
font-size: 33px;
animation-name: rubberBand;
-webkit-backface-visibility: visible !important;
backface-visibility: visible !important;
animation-duration: .75s;
.card-deck .card.not-matching
animation-name: pulse;
-webkit-backface-visibility: visible !important;
backface-visibility: visible !important;
animation-duration: .75s;
background: #e2043b;
.card-deck .card.disabled
pointer-events: none;
opacity: 0.9;
/* SCORE PANEL */
.score-panel
text-align: left;
margin-bottom: 10px;
.score-panel .stars
margin: 0;
padding: 0;
display: inline-block;
margin: 0 5px 0 0;
.score-panel .stars li
list-style: none;
display: inline-block;
.score-panel .restart
float: right;
cursor: pointer;
.fa-star
color: #FFD700;
.timer
display: inline-block;
margin: 0 1rem;
/* CONGRATULATIONS MODAL */
.overlay
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
transition: opacity 500ms;
visibility: hidden;
opacity: 0;
.overlay:target
visibility: visible;
opacity: 1;
.popup
margin: 70px auto;
padding: 20px;
background: #ffffff;
border-radius: 5px;
width: 85%;
position: relative;
transition: all 5s ease-in-out;
font-family: 'Gloria Hallelujah', cursive;
.popup h2
margin-top: 0;
color: #333;
font-family: Tahoma, Arial, sans-serif;
.popup .close
position: absolute;
top: 20px;
right: 30px;
transition: all 200ms;
font-size: 30px;
font-weight: bold;
text-decoration: none;
color: #333;
.popup .close:hover
color: #e5f720;
.popup .congrats-message,
.info-message
max-height: 30%;
overflow: auto;
text-align: center;
.star-rating li
display: inline-block;
.play-again
background-color: #141214;
padding: 0.7rem 1rem;
font-size: 1.1rem;
display: block;
margin: 0 auto;
width: 50%;
font-family: 'Gloria Hallelujah', cursive;
color: #ffffff;
border-radius: 5px;
/* Animations */
@keyframes flipInY
from
transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
animation-timing-function: ease-in;
opacity: 0;
40%
transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
animation-timing-function: ease-in;
60%
transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
opacity: 1;
80%
transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
to
transform: perspective(400px);
@keyframes rubberBand
from
transform: scale3d(1, 1, 1);
30%
transform: scale3d(1.25, 0.75, 1);
40%
transform: scale3d(0.75, 1.25, 1);
50%
transform: scale3d(1.15, 0.85, 1);
65%
transform: scale3d(.95, 1.05, 1);
75%
transform: scale3d(1.05, .95, 1);
to
transform: scale3d(1, 1, 1);
@keyframes pulse
from
transform: scale3d(1, 1, 1);
50%
transform: scale3d(1.2, 1.2, 1.2);
to
transform: scale3d(1, 1, 1);
/* MEDIA QUERIES */
@media (max-width: 320px)
.card-deck
width: 85%;
.card-deck .card
height: 4.7rem;
width: 4.7rem;
/* For tablets and larger screens */
@media (min-width: 768px)
.container
font-size: 22px;
.card-deck
width: 660px;
height: 680px;
.card-deck .card
height: 125px;
width: 125px;
.popup
width: 60%;
<!-- <!doctype html> -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>Matching Game</title>
<meta name="description" content="">
<link rel="stylesheet prefetch" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
<link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Coda">
<link rel="stylesheet" href="index.css">
</head>
<body>
<div class="container">
<header>
<h1>Matching Game</h1>
</header>
<section class="score-panel">
<ul class="stars">
<li><i class="fa fa-star"></i></li>
<li><i class="fa fa-star"></i></li>
<li><i class="fa fa-star"></i></li>
</ul>
<span class="moves">0</span> moves
<div class="timer"></div>
<div class="restart" onclick=startGame()>
<i class="fa fa-repeat"></i>
</div>
</section>
<ul class="card-deck">
<li class="card" type="diamond">
<i class="fa fa-diamond"></i>
</li>
<li class="card" type="plane">
<i class="fa fa-paper-plane-o"></i>
</li>
<li class="card matching" type="anchor">
<i class="fa fa-anchor"></i>
</li>
<li class="card" type="bolt" >
<i class="fa fa-bolt"></i>
</li>
<li class="card" type="cube">
<i class="fa fa-cube"></i>
</li>
<li class="card matching" type="anchor">
<i class="fa fa-anchor"></i>
</li>
<li class="card" type="leaf">
<i class="fa fa-leaf"></i>
</li>
<li class="card" type="bicycle">
<i class="fa fa-bicycle"></i>
</li>
<li class="card" type="diamond">
<i class="fa fa-diamond"></i>
</li>
<li class="card" type="bomb">
<i class="fa fa-bomb"></i>
</li>
<li class="card" type="leaf">
<i class="fa fa-leaf"></i>
</li>
<li class="card" type="bomb">
<i class="fa fa-bomb"></i>
</li>
<li class="card open show" type="bolt">
<i class="fa fa-bolt"></i>
</li>
<li class="card" type="bicycle">
<i class="fa fa-bicycle"></i>
</li>
<li class="card" type="plane">
<i class="fa fa-paper-plane-o"></i>
</li>
<li class="card" type="cube">
<i class="fa fa-cube"></i>
</li>
</ul>
<div class="main-modal overlay">
<div class="popup">
<h2>Congratulations!</h2>
<a class="close" href=# >×</a>
<div class="congrats-message">
Congratulations, you're a winner!
</div>
<div class="info-message">
<p>You made <span class=final-move></span> moves </p>
<p>In <span class=total-time></span></p>
<p>Rating: <span class=star-rating></span></p>
</div>
<button class="play-again" onclick="reset()">
Play again
</button>
</div>
</div>
</div>
<script src="index.js"></script>
</body>
</html>
【讨论】:
以上是关于在记忆游戏中点击卡片不会翻转它的主要内容,如果未能解决你的问题,请参考以下文章