I'm recreating a classic card memory game for my final project - a deck of cards that I need to flip and match. An extract of the deck of cards in HTML is below:
<ul class="deck">
<li class="card">
<i class="fa fa-diamond"></i>
</li>
<li class="card">
<i class="fa fa-paper-plane-o"></i>
</li>
<li class="card">
<i class="fa fa-diamond"></i>
</li>
<li class="card">
<i class="fa fa-paper-plane-o"></i>
</li>
</ul>
I've already added the flip functionality by applying event delegation to the parent node and using the event.target property.
document.querySelector('.deck').addEventListener('click', function(event) {
if (event.target.nodeName === 'LI') {
event.target.classList.add('open');
//get child element "i" classname, add to array and match cards
}
});
Now I need to get the child of the card that was clicked, add that to an array, and then use that array to match two open cards together. Problem is, I can't seem to figure out how to get the child element's class (e.g. i class="fa fa-diamond"). How can I proceed from here?
I thought about just adding an individual event listener to each card instead, but I guess that would be a more costly operation. Or would this be better instead? Looking forward to your help and suggestions.
To get the actual child call querySelector()
from the event.target
passing in a selector that will match your <i>
element, eg i.fa
. Or if it is the only child element of that <li>
just grab the first element in children
var child = event.target.querySelector("i.fa");
//or
var child = event.target.children[0];
Also you do not need to add each element's class(es) to an arayy. Save the card clicked and when the next card is clicked simply compare that to the saved one.
savedI.className == child.className
Demo
var openCard = null;
document.querySelector('.deck').addEventListener('click', function(event) {
//check that we havent clicked on the <li> or child <i>
if (event.target.nodeName !== "LI" && event.target.nodeName !== "I") {
return;
}
var child = null;
if (event.target.nodeName == "LI") {
//if we clicked on the li, child is target.children[0]
child = event.target.children[0];
} else {
//if we clicked on the i directly, child is just the event target
child = event.target;
}
child.parentElement.classList.add('open');
if (openCard && openCard.className == child.className) {
openCard.classList.add("match");
child.classList.add("match");
openCard = null;
console.log("match");
} else if (openCard) {
openCard.parentElement.classList.remove("open");
child.parentElement.classList.remove("open");
openCard = null;
console.log("No match");
} else {
openCard = child;
}
});
i {
height: 32px;
width: 32px;
display: block;
}
.open {
outline: 1px solid #F00;
}
li i.match {
background: #0F0;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
<ul class="deck">
<li class="card">
<i class="fa fa-diamond"></i>
</li>
<li class="card">
<i class="fa fa-paper-plane-o"></i>
</li>
<li class="card">
<i class="fa fa-diamond"></i>
</li>
<li class="card">
<i class="fa fa-paper-plane-o"></i>
</li>
</ul>