javascripthtmlcssarraysbackground-color

How to change the background color of an element in the most efficient way?


I have this square that I would like to change the background color of using buttons.

https://jsfiddle.net/jagupnvc/

<div id="square"></div>
<div>
  <button onclick="colorRed()">Red</button>
  <button onclick="colorYellow()">Yellow</button>
  <button onclick="colorBlue()">Blue</button>
</div>
#square {
  height: 200px;
  width: 200px;
  border: 1px solid black;
}

I've had a few thoughts on how I could do this, but I'd love some input on what would/wouldn't work and how/why.

I do NOT want to implement a "Next" button that uses a loop to cycle through the colors, I would like a button for each color.

The first idea I had would be to make a separate function to change the color for each and every button. Keeping in mind that I'd like to do a dress-up game someday with a ton of different layers/outfit options, this doesn't seem ideal or efficient and I really hope this is not the solution.

The second idea I had would be to somehow make an array of html buttons, an array of css colors classes, and somehow make a function that would link the two somehow? For example, if button1 gets pressed, show .color1, if button2 gets pressed, show .color2, etc.


Solution

  • The easiest way is to give the container of the button an id so you can address it in JS. Then you check with an addEventListener if a click was made within the container. Then you check if a button was clicked (event delegation). Lastly, you read out a data-attribute that has color defined as value and set the background-color of the box with the value of that data-attribtue:

    colors.addEventListener('click', function(event) {
      if (event.target.tagName === 'BUTTON') {
        square.style.backgroundColor = event.target.dataset.color;
      }
    })
    #square {
      height: 200px;
      width: 200px;
      border: 1px solid black;
    }
    <div id="square"></div>
    <div id="colors">
      <button data-color="red">Red</button>
      <button data-color="yellow">Yellow</button>
      <button data-color="blue">Blue</button>
    </div>

    Alternatively, if you want to use an array, you can use the array to loop through the array and create the buttons you want with JS instead of hardcoding it. I would recommend against using an array to link hardcoded buttons with colors. It is an easy way to fail as it would be a maintenance nightmare. Changes must be made within HTML and JS, and they need to fit each other exactly. A thing you should always prevent in modern web coding.

    const COLORS = [
      { name: 'Red',
        color: '#FF0000' },
      { name: 'Yellow',
        color: '#FFFF00' },
      { name: 'Blue',
        color: '#0000FF' },
    ];
    
    window.addEventListener('DOMContentLoaded', function() {
      COLORS.forEach(color => {
        const btn = document.createElement('button');
        btn.textContent = color.name;
        btn.dataset.color = color.color;
        colors.appendChild(btn);
      })
    })
    
    colors.addEventListener('click', function(event) {
      if (event.target.tagName === 'BUTTON') {
        square.style.backgroundColor = event.target.dataset.color;
      }
    })
    #square {
      height: 200px;
      width: 200px;
      border: 1px solid black;
    }
    <div id="square"></div>
    <div id="colors">
    </div>