简体   繁体   中英

Change page background on click to match color of clicked page element using javascript

I am following the tutorial here https://projects.raspberrypi.org/en/projects/cd-beginner-javascript-sushi/8 to make a guess the color game. The last part is a challenge to change the page background when the correct color is guessed. I've managed to change the background but it only returns the color of the last button on the page, not the correct button. Here is a codepen to demonstrate: https://codepen.io/nicdaslick/pen/QWbogQQ .

I understand what's happening, but not how to fix it. The code is inside a for loop but the suggestion in the challenge hints is to change the color inside the for loop. How do I grab the right colors or am I thinking about this wrong?

html:

<body>
<h1>Guess the colour!</h1>
    <h2 id="colourValue"></h2>
    <div id="buttonWrapper">
        <button class="colourButton"></button>
        <button class="colourButton"></button>    
        <button class="colourButton"></button>    
        <button class="colourButton"></button>    
        <button class="colourButton"></button>    
        <button class="colourButton"></button>    
    </div>
    <h2 id="answer"></h2>

    <div id="reset"><button id="resetButton">Reset game</button></div>
</body>

css:

.colourButton{
    background-color: rgb(255,0,0);
    width: 50px;
    height: 50px;
    border: none;
    border-radius: 50%;
    box-shadow: none;
    margin: 10px;
}

#buttonWrapper{
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
    margin: 0 auto;
}

h1{
    text-align: center;
}

#colourValue{
    margin: 0 auto;
    text-align: center;
}

#answer{
    margin: 0 auto;
    text-align: center;
}

#reset{
    margin: 0 auto;
    text-align: center;
}

#reset-button{
    padding: 10px;
    background: none;
    border: 1px solid #000;
    margin: 10px;
}

js:

function makeColourValue(){
  return Math.round(Math.random()*255);
}

function setButtonColour(button, red, green, blue) {
  button.setAttribute(
    'style',
    'background-color: rgb('+ red +','+ green +','+ blue +');'
  );
}

var buttons = document.getElementsByClassName('colourButton');

var heading = document.getElementById('colourValue');

var answerMessage = document.getElementById('answer');

function startGame() {
  answerMessage.innerHTML = "";
  var answerButton = Math.round(Math.random() * (buttons.length - 1));

  for(var i = 0; i < buttons.length; i++) {
    var red = makeColourValue();
    var green = makeColourValue();
    var blue = makeColourValue();

    setButtonColour(buttons[i], red, green, blue);

    if (i === answerButton) {
      heading.innerHTML =`(${red}, ${green}, ${blue})`;
    }

    buttons[i].addEventListener('click', function(){
      if (this === buttons[answerButton]) {
        answerMessage.innerHTML = "Correct!";
        document.body.style.backgroundColor = 'rgb('+ red +','+ green+','+ blue+')';
      } else {
        answerMessage.innerHTML = "Wrong answer! Guess again!";
      }
    });
  }
}

startGame();

document.getElementById('resetButton').addEventListener('click', startGame);

One problem is your use of var instead of let or const .

When you declare a variable with var , it makes a function-scoped variable , no matter where you declare it. Therefore, inside your for loop, red , green , and blue all refer to the same values for each iteration of the loop, rather that you having a distinct value per loop iteration. Think of these variables as being hoisted and declared in the top of your startGame function.

Changing those to const or let should make the variables block-scoped , so they'll exist within the scope of the for loop. This will allow your event listeners which are also declared within the loop to close over unique values per iteration.

I would implore you to never use var ever again ; it has no redeeming qualities over what let or const provide other than allowing your code to run in ancient browsers.

You can pass the event object to your function. Then access the style with event.target.style

buttons[i].addEventListener('click', function(event){
      if (this === buttons[answerButton]) {
        answerMessage.innerHTML = "Correct!";
        document.body.style.backgroundColor = event.target.style.backgroundColor
      } else {
        answerMessage.innerHTML = "Wrong answer! Guess again!";
      }
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM