简体   繁体   English

使用javascript更改点击页面背景以匹配点击页面元素的颜色

[英]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.我正在关注这里的教程https://projects.raspberrypi.org/en/projects/cd-beginner-javascript-sushi/8来猜测颜色游戏。 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 .这是一个用于演示的代码笔: 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.代码在 for 循环内,但挑战提示中的建议是更改 for 循环内的颜色。 How do I grab the right colors or am I thinking about this wrong?我如何获取正确的颜色,或者我是否在考虑这个错误?

html: 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: 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: 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 .一个问题是您使用var而不是letconst

When you declare a variable with var , it makes a function-scoped variable , no matter where you declare it.当您使用var声明变量时,无论您在何处声明它,它都会生成一个函数范围的变量 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.因此,在您的 for 循环中, redgreenblue都指循环的每次迭代的相同值,而不是每次循环迭代都有不同的值。 Think of these variables as being hoisted and declared in the top of your startGame function.将这些变量视为在startGame函数顶部提升和声明的。

Changing those to const or let should make the variables block-scoped , so they'll exist within the scope of the for loop.将它们更改为constlet应该使变量成为块作用域,因此它们将存在于for循环的范围内。 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 ;我恳求你永远不要再使用var it has no redeeming qualities over what let or const provide other than allowing your code to run in ancient browsers.除了允许您的代码在古老的浏览器中运行之外,它对letconst提供的功能没有任何可取之处。

You can pass the event object to your function.您可以将event对象传递给您的函数。 Then access the style with event.target.style然后使用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!";
      }
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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