0
\$\begingroup\$

I have a script that changes the colour, it selects the colour by the id, then it listens what colour was clicked, and if the colour choose was black or whatever other colours, it will do the job.

However, there is a lot of repetition with the if statement. Is there a way to refactor this?

How about if color choosen ${colorClicked} then style bg with = the ${colorAssosiated} or something like that?

Can we re-factor this? But with ES5 best.

var black = document.getElementById("black");
var blue = document.getElementById("blue");
var red = document.getElementById("red");
//01. Listen for button click
var buttonClick = this.addEventListener ("click", function(e) {
 console.log(e.target.id + " button was clicked");
 var colorChosen = e.target.id;
 //02. Change background colour
 if (colorChosen == "black"){
 document.body.style.background = "black";
 console.log('You chose Black!');
 } else if (colorChosen == "blue") {
 document.body.style.background = "blue";
 console.log('You chose Blue!');
 } else if (colorChosen == "red") {
 document.body.style.background = "red";
 console.log('You chose Red!');
 }
});
200_success
146k22 gold badges190 silver badges478 bronze badges
asked Jan 12, 2018 at 9:56
\$\endgroup\$
1
  • 1
    \$\begingroup\$ You don't need the if... else or even the template literals, if the colours are only those ones: jsfiddle.net/dcydzbw3. Also, your code doesn't seem to be complete. What are those elements at the beginning? And what is this in this context? When asking a question at CR please try to make the code "complete" for reviewing purposes. \$\endgroup\$ Commented Jan 12, 2018 at 10:04

2 Answers 2

3
\$\begingroup\$

I think in your case you can just do this:

document.body.style.background = colorChosen;

Avoiding all the ugly if else part.

A more robust solution will be using a lookup table to decouple the DOM ids from the proper colors string:

const colorFor = {
 "somethingRed": "red",
 "somethingBlue": "blue",
 "somethingBlack": "black"
};
...
document.body.style.background = colorFor[colorChosen];

With somethingBlaBla I mean a meaninful name that not contains the color. The purpose is to contain the changes in case you want a different color in the future or if you want that more options have the same color.

Another improvement is to have a guard condition to avoid errors or weird situations:

var buttonClick = this.addEventListener ("click", function(e) {
 console.log(e.target.id + " button was clicked");
 var colorChosen = e.target.id;
 if (!colorFor[colorChosen])
 return false;
 document.body.style.background = colorFor[colorChosen];
});

Instead of just return from the function you can log an error or pup up a dialog with a warning to inform the user. Or you can reset to a default color the background.

In the same way you can use a style instead of setting the color on the DOM element.

This could be better in some situation, depends on your app code convention.

answered Jan 12, 2018 at 10:12
\$\endgroup\$
1
\$\begingroup\$

I would recommend using data attributes on your buttons, something like:

<button data-color="black">Black!</button>

And then:

var buttonClick = this.addEventListener ("click", function(e) {
 var button = e.target;
 if (!button.hasAttribute('data-color'))
 return;
 document.body.style.background = button.getAttribute('data-color');
});

Also I'm not sure what this is set to here:

var buttonClick = this.addEventListener ("click", function(e) {

But in a global call this usually refers to the window and this will process clicks on any element. You should rather add the listener to the button's nearest container.

answered Jan 12, 2018 at 20:05
\$\endgroup\$
1
  • \$\begingroup\$ I think this answer is better, since it completely decouples the color from the id. This is exactly what data tags are meant to do. Hold additional data which is not meant for other tags. It's also easier to add more buttons, since you don't have to change anything in the code. \$\endgroup\$ Commented Jan 16, 2018 at 12:30

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.