0

I'm trying to make a game in which a green square appear in a random place for 2 seconds then disappears and spears again in different place. If the user clicks on the green square, then they receive one point. When they click on a white square, then they lose a life.

I don't know how to retrieve the green square in my Javascript code. I thought that I'd give the green square class green and white squares class white and then do something like that:

document.getElementsByClassName('green').onclick(() => {
    //give the user a point
}

document.getElementsByClassName('white').onclick(() => {
    //user loses a life
}

...but unfortunately it doesn't work.

Do you know why? How can I do it?

You can see how the game looks here: https://zylka44.github.io/reflex/

...and whole script.js here: https://github.com/zylka44/reflex/blob/master/script.js

let start = document.getElementById('start');

//here I create the board contains 5 rows of 5 squares
const makeBoard = () => {
  let board = '';
  for (i = 0; i < 5; i++) {
    let row = '<div class="row">';
    for (j = 0; j < 5; j++) {
      let numer = 5 * i + j;
      row += `<div id="sq${numer}" class="square"></div>`;
    };
    row = row + '</div>';

    board += row;
  }
  document.getElementById('board').innerHTML = board;
}

//here I randomize where the green square should apear
const randomSquare = () => {
  let randId = 'sq' + Math.floor(Math.random() * 25);
  document.getElementById(randId).className += " green";

  setTimeout(() => {
    document.getElementById(randId).style.backgroundColor = 'white';
  }, 2000);

}


//the board apears
makeBoard();

start.onclick = () => {
  randomSquare();
  setInterval(() => {
    randomSquare();
  }, 3000);

  countdown();
};

// time is counting down (60 sek)
const countdown = () => {
  let count = 60;
  let timerCounter = setInterval(() => {
    count--;
    document.getElementById('time').innerHTML = count;
    if (count <= 0) {
      clearInterval(timerCounter);
      document.getElementById('alert').style.color = 'rgb(184, 60, 60)';
      document.getElementById('alert').innerHTML = 'Time is up!';
      document.getElementById('game_over').style.display = 'block';
    }
  }, 1000);
};
body {
    text-align: center;
    font-family: Caveat;
    font-size: 32px;
}

/*header*/
#header {
    display: flex;
    justify-content: center;
    min-width: 810px;
    width: 90%;
    margin: 20px auto;
}

.box_in_header {
    width: 270px;
}

.bold {
    font-weight: bold;
}

#counterbox {
    display: flex;
}

.counter {
    margin: 0 20px;
}

#time, #lifes, #points {
    display: inline;
}

/*plansza*/
#container {
    display: inline-block;
    justify-content: center;
    min-width: 810px;
    margin: 20px auto;
}

#alert {
    height: 40px;
    color:rgb(18, 156, 87);
    margin-bottom: 10px;
}

#board {
    position: relative;
}

.row {
    display: flex;
    justify-content: center;
}

.square {
    width: 40px;
    height: 40px;
    border: 1px solid black;
    margin: 5px;
    cursor: pointer;
    background-color: white;
}

#game_over {
    display: none;
    width: 810px;
    height: 270px;
    background-color:rgba(255,255,255,0.7);
    position: absolute;
    top: 150px;
}

.green {
    background-color: rgb(18, 156, 87);
}

.white {
    background-color: white;
}

/*start i reset*/
#start-reset {
    display: flex;
    justify-content: center;
    margin: 10px auto;
}

#start {
    margin: 0 40px;
    cursor: pointer;
}

#reset {
    margin: 0 40px;
    cursor: pointer;
}
<div id="header">
  <div id="counterbox" class="box_in_header">
    <div class="counter">Lifes:
      <div id="lifes">3</div>
    </div>
    <div class="counter">Points:
      <div id="points">0</div>
    </div>
  </div>
  <div class="box_in_header bold">REFLEX</div>
  <div class="box_in_header">Time:
    <div id="time">60</div> sek</div>
</div>

<!--plansza-->
<div id="container">
  <!--alert-->
  <div id="alert">Catch the green square!</div>

  <!--kwadraty-->
  <div id="board"></div>
  <div id="game_over"></div>

  <!--start i reset-->
  <div id="start-reset">
    <div id="start">Start</div>
    <div id="reset">Reset</div>
  </div>


</div>
Zaneta
  • 3
  • 3
  • `document.getElementById('white')`is not the same as getElementsByClassName. It seems to me you are learning JS and you need to have a good look at what options you have to select elements: `document.querySelectorAll()` is something you can use. – cloned Jul 15 '19 at 14:14
  • Sorry, I did mistake, I thougth about getElementByClassName but I wrote wrong – Zaneta Jul 15 '19 at 14:20

3 Answers3

0

You need to loop thru the elements and add the event handlers individually.

Array.from(document.getElementsByClassName('white')).forEach(ele=>ele.onclick(() => {
    //user loses a life
});
I wrestled a bear once.
  • 22,983
  • 19
  • 69
  • 116
  • I did not vote down for not supporting IE. I voted down for inelegant looping over all elements when you can delegate – mplungjan Jul 15 '19 at 14:40
0

Use event.target and listen on click on the board

document.getElementById("board").addEventListener("click",(e) => {
  var tgt = e.target;
  if (!tgt.classList.contains("square")) return;
  if (tgt.classList.contains("green")) {
    console.log("Win a point")
  }
  else {
    console.log("Lose a life")
  }
});

let start = document.getElementById('start');

//here I create the board contains 5 rows of 5 squares
const makeBoard = () => {
  let board = '';
  for (i = 0; i < 5; i++) {
    let row = '<div class="row">';
    for (j = 0; j < 5; j++) {
      let numer = 5 * i + j;
      row += `<div id="sq${numer}" class="square"></div>`;
    };
    row = row + '</div>';

    board += row;
  }
  document.getElementById('board').innerHTML = board;
}

//here I randomize where the green square should apear
const randomSquare = () => {
  let randId = 'sq' + Math.floor(Math.random() * 25);
  document.getElementById(randId).className += " green";

  setTimeout(() => {
    document.getElementById(randId).style.backgroundColor = 'white';
  }, 2000);

}


//the board apears
makeBoard();

start.onclick = () => {
  randomSquare();
  setInterval(() => {
    randomSquare();
  }, 3000);

  countdown();
};

// time is counting down (60 sek)
const countdown = () => {
  let count = 60;
  let timerCounter = setInterval(() => {
    count--;
    document.getElementById('time').innerHTML = count;
    if (count <= 0) {
      clearInterval(timerCounter);
      document.getElementById('alert').style.color = 'rgb(184, 60, 60)';
      document.getElementById('alert').innerHTML = 'Time is up!';
      document.getElementById('game_over').style.display = 'block';
    }
  }, 1000);
};
document.getElementById("board").addEventListener("click",(e) => {
  var tgt = e.target;
  if (!tgt.classList.contains("square")) return;
  if (tgt.classList.contains("green")) {
    console.log("Win a point")
  }
  else {
    console.log("Lose a life")
  }
});
body {
    text-align: center;
    font-family: Caveat;
    font-size: 32px;
}

/*header*/
#header {
    display: flex;
    justify-content: center;
    min-width: 810px;
    width: 90%;
    margin: 20px auto;
}

.box_in_header {
    width: 270px;
}

.bold {
    font-weight: bold;
}

#counterbox {
    display: flex;
}

.counter {
    margin: 0 20px;
}

#time, #lifes, #points {
    display: inline;
}

/*plansza*/
#container {
    display: inline-block;
    justify-content: center;
    min-width: 810px;
    margin: 20px auto;
}

#alert {
    height: 40px;
    color:rgb(18, 156, 87);
    margin-bottom: 10px;
}

#board {
    position: relative;
}

.row {
    display: flex;
    justify-content: center;
}

.square {
    width: 40px;
    height: 40px;
    border: 1px solid black;
    margin: 5px;
    cursor: pointer;
    background-color: white;
}

#game_over {
    display: none;
    width: 810px;
    height: 270px;
    background-color:rgba(255,255,255,0.7);
    position: absolute;
    top: 150px;
}

.green {
    background-color: rgb(18, 156, 87);
}

.white {
    background-color: white;
}

/*start i reset*/
#start-reset {
    display: flex;
    justify-content: center;
    margin: 10px auto;
}

#start {
    margin: 0 40px;
    cursor: pointer;
}

#reset {
    margin: 0 40px;
    cursor: pointer;
}
<div id="header">
  <div id="counterbox" class="box_in_header">
    <div class="counter">Lifes:
      <div id="lifes">3</div>
    </div>
    <div class="counter">Points:
      <div id="points">0</div>
    </div>
  </div>
  <div class="box_in_header bold">REFLEX</div>
  <div class="box_in_header">Time:
    <div id="time">60</div> sek</div>
</div>

<!--plansza-->
<div id="container">
  <!--alert-->
  <div id="alert">Catch the green square!</div>

  <!--kwadraty-->
  <div id="board"></div>
  <div id="game_over"></div>

  <!--start i reset-->
  <div id="start-reset">
    <div id="start">Start</div>
    <div id="reset">Reset</div>
  </div>


</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
-1
const allElementsWithClass = document.getElementsByClassName(className);

Will give you an array of all elements with the class. To access one element from this class you need to use the index. If there is only one element in the array you can use

const firstElement = allElementsWithClass[0];
firstElement.onclick(() => {/* user loses a life here */});

If you want to set onclick for each element with the class.

allElementsWithClass.forEach(element=>{element.onclick(()=>{/* user loses a life here*/})})
Pranav Nachnekar
  • 115
  • 1
  • 10
  • 1
    `getElementsByClass` is not a method. `getElementsByClassName` however, returns an HTMLCollection, not a nodeList, which does not implement `forEach`. – I wrestled a bear once. Jul 15 '19 at 14:25
  • I wrote ```const squares = document.getElementsByClassName('white'); const firstElement = squares[0]; firstElement.onclick(() => {console.log('ok')}); ``` but I receive >firstElement.onclick is not a function – Zaneta Jul 15 '19 at 14:53