0

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.

James
  • 3
  • 2
  • Welcome to SO, why not try what you're thinking and if you have issues, let us know and we might be able to help. This is not a place for advice as such but happy to help with specific problems you come up against – StudioTime Nov 17 '18 at 19:19

1 Answers1

0

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>
Patrick Evans
  • 41,991
  • 6
  • 74
  • 87