Reputation: 1390
I am using "multi-criteria cases" in my switch
statement in order to handle the different values I am getting.
One of the things I am running into is this (dummy code from snippet below):
case '2':
// Don't mind the inline styling, its' only for this example
document.getElementById('output').lastChild.style.color = 'red';
case '2.5':
document.getElementById('output').lastChild.style.color = 'white';
document.getElementById('output').lastChild.style.backgroundColor = 'blue';
break;
What I am attempting to do here is to set either 2
or 2.5
's background color to be blue, but still set the text color uniquely based on the value.
Only that, like the code was meant to do, it overrides the text color of 2
with the text color of 2.5
.
The first is:
case '2':
document.getElementById('output').lastChild.style.color = 'red';
document.getElementById('output').lastChild.style.backgroundColor = 'blue';
break;
case '2.5':
document.getElementById('output').lastChild.style.color = 'white';
document.getElementById('output').lastChild.style.backgroundColor = 'blue';
break;
The second is:
case '2':
document.getElementById('output').lastChild.style.color = 'red';
case '2.5':
if (e.target.textContent === '2.5') {
document.getElementById('output').lastChild.style.color = 'white';
}
document.getElementById('output').lastChild.style.backgroundColor = 'blue';
break;
The only real problem now is that I am a big fan of the "DRY" theory. The above two solutions are, to some degree, "WET."
Thus I am trying to figure out a better way to write this code, potentially something which looks like this:
case '2':
document.getElementById('output').lastChild.style.color = 'red';
case '2.5':
document.getElementById('output').lastChild.style.color = 'white';
case '2':
case '2.5':
document.getElementById('output').lastChild.style.backgroundColor = 'blue';
break;
(Even this is a bit "DRY")
I understand that to some degree my code will be a bit "DRY" and I am willing to have that if necessary, I am just at the stage of lessening the code I do have for performance and want to see if I can cut the code down in any way possible.
Here's a snippet with my dummy code in action:
document.addEventListener('click', function(e) {
if (e.target.nodeName === 'BUTTON') {
document.getElementById('output').innerHTML += '<div>' + e.target.textContent + '</div>';
switch(e.target.textContent) {
case '1':
// Don't mind the inline styling for this example pls
document.getElementById('output').lastChild.style.backgroundColor = 'green';
break;
case '2':
document.getElementById('output').lastChild.style.color = 'red';
case '2.5':
document.getElementById('output').lastChild.style.color = 'white';
document.getElementById('output').lastChild.style.backgroundColor = 'blue';
break;
case '3':
document.getElementById('output').lastChild.style.color = 'lime';
case '3.5':
if (e.target.textContent === '3.5') {
document.getElementById('output').lastChild.style.color = 'cyan';
}
document.getElementById('output').lastChild.style.backgroundColor = 'red';
break;
}
}
});
<button id="b1">1</button>
<button id="b2">2</button>
<button id="b2-5">2.5</button>
<button id="b3">3</button>
<button id="b3-5">3.5</button>
<div id="output"></div>
Going on, I figured there was another way to do this, which looks like this:
switch(e.target.textContent) {
case '2':
case '2.5':
switch(e.target.textContent) {
case '2':
document.getElementById('output').lastChild.style.color = 'red';
break;
case '2.5':
document.getElementById('output').lastChild.style.color = 'white';
break;
}
document.getElementById('output').lastChild.style.backgroundColor = 'blue';
break;
}
However, that basically is two of the same switch
statements nested in one another.
I am not trying to write all the wrong ways to do things (I know it looks like that), I am trying to figure out the right way to do it, maybe by testing all the wrong ways to do it.
If anyone can help me with the right way to do this, that would be much appreciated.
Upvotes: 1
Views: 64
Reputation: 198
You could do something like:
var config = {
"1" : {
"bgColor": "green"
},
"2" : {
"bgColor": "red"
},
"2.5" : {
"color": "white",
"bgColor": "blue"
},
"3" : {
"color": "lime"
},
"3.5" : {
"color": "cyan",
"bgColor": "red"
}
};
document.addEventListener('click', function(e) {
if (e.target.nodeName === 'BUTTON') {
var output = document.getElementById('output');
output.innerHTML += '<div>' + e.target.textContent + '</div>';
for(var key in config) {
if(e.target.textContent == key) {
var obj = config[key];
if(obj['color']) {
output.lastChild.style.color = obj['color'];
}
if(obj['bgColor']) {
output.lastChild.style.backgroundColor = obj['bgColor'];
}
}
}
}
});
This way you can just edit the data layer (JSON) when you need to add more options. You also won't need to touch the click event.
Upvotes: 0
Reputation: 1161
This might be a slightly simplified solution. Is this what you're looking for?
document.addEventListener('click', function(e) {
if (e.target.nodeName === 'BUTTON') {
var elem = document.getElementById('output');
elem.innerHTML += '<div>' + e.target.textContent + '</div>';
var txColor = '',
bgColor = '',
elemStyle = elem.lastChild.style;
switch(e.target.textContent) {
case '1':
bgColor = 'green';
break;
case '2':
txColor = 'red';
case '2.5':
txColor = 'white';
bgColor = 'blue';
break;
default:
bgColor = 'red';
txColor = (e.target.textContent === '3.5') ? 'cyan':'lime';
}
elemStyle.color = txColor;
elemStyle.backgroundColor = bgColor;
}
});
<button id="b1">1</button>
<button id="b2">2</button>
<button id="b2-5">2.5</button>
<button id="b3">3</button>
<button id="b3-5">3.5</button>
<div id="output"></div>
Upvotes: 2