0

I am facing an issue while coding for a small project. Basically, I am trying to make a flip box which, upon clicked by a user will show him if its any of the superhero mentioned in an array. Please take a look at this code pen to have an idea about it: https://codepen.io/zakero/pen/YmGmwK .

The code works perfectly when I am using alert(), as you can see in code pen. It randomizes every time a square is clicked. But I want the result to be displayed after it's clicked and flipped. I mean instead of "Back", I want it to be the random names of the superheroes. I have both tried .textContent and .innerHTML to change it but it doesn't seem to work This is the code I have tried:

Javascript:

function setupSquares() {
    for(var i = 0; i < frontSquare.length; i++) {
        frontSquare[i].addEventListener("click", function() {
            var randomNumber = frontSquare[i] = generateRandomNumbers(numbers);
            for(var j = 0; j < superhero.length; j++) {
                var index = superhero.indexOf(superhero[j]);
                if(randomNumber === index){
                    backSquare.textContent = superhero[j];
                }
            }

        });
    }
}

var superhero = ["Ironman", "Superman", "Batman", "Spiderman", "Black Panther", "Hawkeye", "Hulk", "Captain America", "Thor", "Quicksilver", "Loki"];
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var frontSquare = document.querySelectorAll(".front");
var backSquare = document.querySelectorAll(".back");


init();

function init() {
  setupSquares();
}

function generateRandomNumbers(num) {
  var random = Math.floor(Math.random() * num.length + 1);
  return random;
}

function setupSquares() {
  for (var i = 0; i < frontSquare.length; i++) {
    frontSquare[i].addEventListener("click", function() {
      var randomNumber = frontSquare[i] = generateRandomNumbers(numbers);
      for (var j = 0; j < superhero.length; j++) {
        var index = superhero.indexOf(superhero[j]);
        if (randomNumber === index) {
          alert(superhero[j]);
        }
      }

    });
  }
}
@import url(https://fonts.googleapis.com/css?family=Open+Sans);
body {
  background: #96CEB4;
  font-family: Open Sans;
  font-size: 50px;
  color: #222;
}

#container {
  margin: 37px auto;
  max-width: 1000px;
  background: #96CEB4;
  height: 550px;
  overflow: hidden;
}

.square {
  width: 30%;
  padding-top: 35px;
  margin: 1.66%;
  float: left;
  -webkit-perspective: 1000px;
  perspective: 1000px;
  -webkit-transform-style: preserve-3d;
  transform-style: preserve-3d;
  display: block;
  height: 200px;
  -webkit-transform: translate(0%, 0%);
  transform: translate(0%, 0%);
  cursor: pointer;
  /*border-radius: 50px;*/
}

.card {
  position: relative;
  height: 100%;
  width: 100%;
  -webkit-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-transition: all 600ms;
  transition: all 600ms;
  z-index: 20;
}

.card div {
  position: absolute;
  height: 100%;
  width: 100%;
  background: #FFEEAD;
  text-align: center;
  line-height: 200px;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  border-radius: 10px;
}

.card .back {
  background: #FF6F69;
  color: #FFF;
  -webkit-transform: rotateX(180deg);
  transform: rotateX(180deg);
}

label:hover .card {
  -webkit-transform: rotateX(20deg);
  transform: rotateX(20deg);
  box-shadow: 0 20px 20px rgba(50, 50, 50, .2);
}

input {
  display: none;
}

:checked+.card {
  transform: rotateX(180deg);
  -webkit-transform: rotateX(180deg);
}

label:hover :checked+.card {
  transform: rotateX(160deg);
  -webkit-transform: rotateX(160deg);
  box-shadow: 0 20px 20px rgba(255, 255, 255, .2);
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <link rel="stylesheet" type="text/css" href="css/style.css">

  <title>Flip Box</title>
</head>

<body>

  <div id="container">
    <label class="square">
      <input type="checkbox"/>
      <div class="card">
          <div class="front">Front</div>
          <div class="back">Back</div>
      </div>
  </label>
    <label class="square">
      <input type="checkbox"/>
      <div class="card">
          <div class="front">Front</div>
          <div class="back">Back</div>
      </div>
  </label>
    <label class="square">
      <input type="checkbox"/>
      <div class="card">
          <div class="front">Front</div>
          <div class="back">Back</div>
      </div>
  </label>
    <label class="square">
      <input type="checkbox"/>
      <div class="card">
          <div class="front">Front</div>
          <div class="back">Back</div>
      </div>
  </label>
    <label class="square">
      <input type="checkbox"/>
      <div class="card">
          <div class="front">Front</div>
          <div class="back">Back</div>
      </div>
  </label>
    <label class="square">
      <input type="checkbox"/>
      <div class="card">
          <div class="front">Front</div>
          <div class="back">Back</div>
      </div>
  </label>
  </div>






  <script type="text/javascript" src="js/script.js"></script>
</body>

</html>
nmak18
  • 1,059
  • 8
  • 24
Zak
  • 860
  • 16
  • 39
  • `backSquare` is an array of dom elements, it holds every square, you need to choose which one the text will show up on. If you do `backSquare[0].textContent = superhero[j]` Then the back of the first card will change. Hopefully you get the idea. – SpeedOfRound Jul 26 '19 at 15:48
  • @SpeedOfRound careful though! Since he's using `var` instead of `let` you don't have a closure over `i` in the loop – mehulmpt Jul 26 '19 at 15:53
  • Thanks @SpeedOfRound for pointing it out. – Zak Jul 26 '19 at 16:50

2 Answers2

1

You could get to the .back of the .front clicked using the following:

this.parentNode.querySelector('.back').innerText = superhero[j];

You see, for your case, you're missing a bunch of things. First of all backSquare is an array, so you have to access the element which you want to modify out of it. Instead of backSquare.textContent = superhero[j];, use backSquare[i].innerText = superhero[j] which allows you to access the same i-th backSquare as frontSquare. But careful, this would not work because you're using var i = ... in the loop variable and var doesn't create a closure over the loop. So to fix that, you could change var to let.

More about this here: Closures versus ES6 Let

Or, you could use this which refers to the current element being clicked. this gets populated by the current element being clicked with your addEventListener function.

More about this: https://codeburst.io/all-about-this-and-new-keywords-in-javascript-38039f71780c

Demo: https://codepen.io/anon/pen/JgbPEK

mehulmpt
  • 15,861
  • 12
  • 48
  • 88
  • Hey it works perfectly now. Thank you. If you don't mind can you please explain where my issue was? Was it specificity of choosing .back class? Also can you please tell me what "this" keyword refers to? – Zak Jul 26 '19 at 16:08
0

You can also do it like this this.closest('.card').querySelector('.back').textContent = superhero[j]