0

I've started to make a memory game but I have a problem:

let card = [];

function makeCards() {

  let cardSymbol = [];

  const scorePan = document.querySelector('section');

  scorePan.insertAdjacentHTML('afterend', '<ul class="deck"></ul>');

  const cardDeck = document.querySelector('.deck');


  for (let i = 1; i < 17; i++) {

    card[i] = document.createElement('li');

    card[i].setAttribute('class', 'card');

    cardSymbol[i] = document.createElement('i');

    cardSymbol[i].setAttribute('class', `fa fa-${symbols[i]}`);

    card[i].appendChild(cardSymbol[i]);

    cardDeck.appendChild(card[i]);
  }


}

makeCards();

So int the array card I've stored all the cards, and added the cards in function makeCards , the problem is I want to add an Event Listener in another function to every single card, but if I iterate over the elements with a for loop and I console.log() every element it shows me undefined, and this happens either I write the loop in a function or outside any function, but If I console.log(card) ; it shows me an array that contains all the elements of the array. Why I can't loop over them since I have an array?? Or should I add the eventListerns to elements when I create them in the function makeCards?????

Ori Drori
  • 183,571
  • 29
  • 224
  • 209
J.Doe
  • 35
  • 1
  • 4

2 Answers2

0

You need a live event listener. If you are using jQuery you can use this

or if you are using native js, you can implement this

user1496463
  • 410
  • 3
  • 14
  • `native js` as in pure unadulterated JS without any plugins, tools or libraries. https://stackoverflow.com/questions/7022007/what-is-native-javascript – user1496463 Apr 27 '18 at 04:30
0

We can set one element that is a common ancestor to all card elements to listen for a "click" event occuring on it and/or its descendants. This is possible because of how an event bubbles. For details on this procedure read this article about Event Delegation.

The following Demo creates 2 arrays of matched FA classes and shuffles them. The ancestor element is created as deck and its descendant elements are card, and face elements which are created on each iteration of a for loop. Only the basic function of flipping is provided for each card/face, the logic for matching is beyond the scope of the OP question and requires a separate question to be posted.

Demo

Details are commented in Demo

/* Hardcode FA classes in symbol array
== Clone symbol array
== Use shuffle() function on both arrays
== Merge both arrays into faces array
*/
var symbol = ['fa-pied-piper-alt', 'fa-heart', 'fa-star', 'fa-star-o', 'fa-paw', 'fa-leaf', 'fa-cube', 'fa-cubes', 'fa-rebel', 'fa-empire'];
var match = symbol.slice(0);
var topCut = shuffle(symbol);
var bottomCut = shuffle(match);
var faces = topCut.concat(bottomCut);

// Create and reference parent element
var stack = document.createElement('main');
stack.id = 'deck';

// for each loop...
for (let c = 0; c < match.length * 2; c++) {

  // Create a card element and add attributes
  var card = document.createElement('a');
  card.href = '#/';
  card.classList.add.apply(card.classList, ['card', 'cover']);

  /* Create a face element and add attributes
  || Note: each face is assigned a FA icon but not .fa class
  */
  var face = document.createElement('i');
  face.classList.add('face');
  face.classList.add(faces[c]);

  // Add each face to a card and each card to the deck (stack)
  card.appendChild(face);
  stack.appendChild(card);
}

// When complete, add deck to DOM
document.body.appendChild(stack);

// Reference deck
var deck = document.getElementById('deck');

/* Register deck to click event
|| When deck and/or its descendant elements are clicked...
|| invoke callback function flip()
*/
deck.addEventListener('click', flip, false);

// Pass Event Object
function flip(event) {

  // Prevent <a> from jumping to a location
  event.preventDefault();

  /* event.target: origin of click event (clicked element)
  || event.currentTarget: element that listens for click (#deck)
  || if the clicked element is NOT #deck...
  */
  if (event.target !== event.currentTarget) {

    //...and if that clicked element is an <a>...
    if (event.target.tagName === "A") {

      /* toggle clicked <a> class .cover and 
      || its child <i> class .fa on/off
      */
      event.target.classList.toggle('cover');
      var trump = event.target.firstElementChild;
      trump.classList.toggle('fa');
    }
  }
}


// Utility function uses Fisher-Yates algorithm to shuffle arrays
function shuffle(array) {
  var i = 0;
  var j = 0;
  var temp = null;
  for (i = array.length - 1; i > 0; i -= 1) {
    j = Math.floor(Math.random() * (i + 1))
    temp = array[i]
    array[i] = array[j]
    array[j] = temp
  }
  return array;
}
#deck {
  display: flex;
  flex-flow: row wrap;
  width: 450px;
  height: 300px;
  border-radius: 6px;
  border: 5px inset brown;
  background: green;
}

.card {
  text-decoration: none;
  display: inline-block;
  width: 48px;
  height: 64px;
  border-radius: 6px;
  border: 3px solid #000;
  background: #fff;
  font-size: 40px;
  text-align: center;
  margin: 5px
}

.face {
  transform: translateY(11px);
  pointer-events: none;
  color: inherit;
}

.cover {
  color: transparent;
  background: #fff;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
Community
  • 1
  • 1
zer00ne
  • 41,936
  • 6
  • 41
  • 68