Switch case

Hey everyone, I have this code
/* eslint-disable import/extensions */
import wait from '../utils/wait.js';

const monitor = document.querySelector('.monitor');
const monitorBody = document.querySelector('.monitor-body');
const monitorLeg = document.querySelector('.monitor-leg');

const languageIcon = document.querySelector('.language-icon');

const languageIcons = [
'html icon.svg',
'css icon.svg',
'javascript icon.svg',
'python icon.svg',
'svelte icon.svg',
];

async function rotateIcons(icons) {
for (let icon = 0; languageIcons.length > 0; icon += 1) {
if (icon === languageIcons.length) {
icon = 0;
}

languageIcon.href.baseVal = `/images/${languageIcons[icon]}`;

switch (languageIcons[icon]) {
case 'html icon.svg':
monitor.classList.remove('svelte-svg-monitor-fill');
monitor.classList.add('html-svg-monitor-fill');
break;
case 'css icon.svg':
monitor.classList.remove('html-svg-monitor-fill');
monitor.classList.add('css-svg-monitor-fill');
break;
case 'javascript icon.svg':
monitor.classList.remove('css-svg-monitor-fill');
monitor.classList.add('javascript-svg-monitor-fill');
break;
case 'python icon.svg':
monitor.classList.remove('javascript-svg-monitor-fill');
monitor.classList.add('python-svg-monitor-fill');
monitorLeg.classList.add('python-svg-leg-fill');
break;
case 'svelte icon.svg':
monitor.classList.remove('python-svg-monitor-fill');
monitorLeg.classList.remove('python-svg-leg-fill');
monitor.classList.add('svelte-svg-monitor-fill');
break;

default:
break;
}

// eslint-disable-next-line no-await-in-loop
await wait(2000);
}
}

if (languageIcon) rotateIcons(languageIcons);
/* eslint-disable import/extensions */
import wait from '../utils/wait.js';

const monitor = document.querySelector('.monitor');
const monitorBody = document.querySelector('.monitor-body');
const monitorLeg = document.querySelector('.monitor-leg');

const languageIcon = document.querySelector('.language-icon');

const languageIcons = [
'html icon.svg',
'css icon.svg',
'javascript icon.svg',
'python icon.svg',
'svelte icon.svg',
];

async function rotateIcons(icons) {
for (let icon = 0; languageIcons.length > 0; icon += 1) {
if (icon === languageIcons.length) {
icon = 0;
}

languageIcon.href.baseVal = `/images/${languageIcons[icon]}`;

switch (languageIcons[icon]) {
case 'html icon.svg':
monitor.classList.remove('svelte-svg-monitor-fill');
monitor.classList.add('html-svg-monitor-fill');
break;
case 'css icon.svg':
monitor.classList.remove('html-svg-monitor-fill');
monitor.classList.add('css-svg-monitor-fill');
break;
case 'javascript icon.svg':
monitor.classList.remove('css-svg-monitor-fill');
monitor.classList.add('javascript-svg-monitor-fill');
break;
case 'python icon.svg':
monitor.classList.remove('javascript-svg-monitor-fill');
monitor.classList.add('python-svg-monitor-fill');
monitorLeg.classList.add('python-svg-leg-fill');
break;
case 'svelte icon.svg':
monitor.classList.remove('python-svg-monitor-fill');
monitorLeg.classList.remove('python-svg-leg-fill');
monitor.classList.add('svelte-svg-monitor-fill');
break;

default:
break;
}

// eslint-disable-next-line no-await-in-loop
await wait(2000);
}
}

if (languageIcon) rotateIcons(languageIcons);
10 Replies
NazCodeland
NazCodelandOP2y ago
This is just the switch case code within a bigger code that loop over an array of svg files and every 2 seconds replaces the svg shown What I don't like about this switch case statement is that, I need to remove the the previously added class in the next switch case It would be great if there was a way to have a switch case that ran for all cases, that way I can just have in there all the remove functions once is there a way to achieve that?
MarkBoots
MarkBoots2y ago
can you show us some more code ? (Make a small example in codepen) . Because i have the feeling this could be way easier (even in css)
WillsterJohnson
From that switch statement it looks like the cases aren't removing all of the classes that could be present. eg the python one only removes javascript, but there could be css or html etc. First investigate doing this with CSS as mark suggested. CSS is way faster than JS, so if you can get something done there, do it there. If JS is the only way though; You could make a separate removeUnwantedClasses function, something like;
/**
* @param {HTMLElement] element - the element to remove classes from
* @param {string[]} classes - the classes to remove
*/
function removeUnusedClasses(element, classes) {
for (const className of classes) element.classList.remove(className)
}
/**
* @param {HTMLElement] element - the element to remove classes from
* @param {string[]} classes - the classes to remove
*/
function removeUnusedClasses(element, classes) {
for (const className of classes) element.classList.remove(className)
}
Then in your existing code;
// ...
const classes = [/* ... */];
// ...
removeUnusedClasses(monitor, classes);
switch (languageIcons[icon]) // ...
// ...
// ...
const classes = [/* ... */];
// ...
removeUnusedClasses(monitor, classes);
switch (languageIcons[icon]) // ...
// ...
NazCodeland
NazCodelandOP2y ago
I updated the original post to include all the code from the file.js I should have included all the code to begin with, but all the classes remove the one before it so all classes are getting removed // html snippet of the inline svg
<svg ...>
<path class="monitor" ... fill="#145883"/>
<image class="language-icon" href="" height="45" width="45" x="45" y="19"/>
<path class="monitor-body" .../>
<path class="monitor-leg" ... fill="#D9D9D9"/>
</svg>
<svg ...>
<path class="monitor" ... fill="#145883"/>
<image class="language-icon" href="" height="45" width="45" x="45" y="19"/>
<path class="monitor-body" .../>
<path class="monitor-leg" ... fill="#D9D9D9"/>
</svg>
export default function removeUnusedClasses(element, classes) {
if (classes) {
const classesArray = Array.of(classes);
for (const className of classesArray) {
element.classList.remove(className);
}
}
}
export default function removeUnusedClasses(element, classes) {
if (classes) {
const classesArray = Array.of(classes);
for (const className of classesArray) {
element.classList.remove(className);
}
}
}
removeUnusedClasses(monitor, monitor.classList.value);
removeUnusedClasses(monitorBody, monitorBody.classList.value);
removeUnusedClasses(monitorLeg, monitorLeg.classList.value);


switch (languageIcons[icon]) {
case 'html icon.svg':
monitor.classList.add('html-svg-monitor-fill');
break;

case 'css icon.svg':
monitor.classList.add('css-svg-monitor-fill');
break;

case 'javascript icon.svg':
monitor.classList.add('javascript-svg-monitor-fill');
break;

case 'python icon.svg':
monitor.classList.add('python-svg-monitor-fill');
monitorLeg.classList.add('python-svg-leg-fill');
break;

case 'svelte icon.svg':
monitor.classList.add('svelte-svg-monitor-fill');
monitorBody.classList.add('svelte-svg-body-fill');
monitorLeg.classList.add('svelte-svg-leg-fill');
break;

case 'github icon.svg':
monitor.classList.add('github-svg-monitor-fill');
break;

default:
break;
}
removeUnusedClasses(monitor, monitor.classList.value);
removeUnusedClasses(monitorBody, monitorBody.classList.value);
removeUnusedClasses(monitorLeg, monitorLeg.classList.value);


switch (languageIcons[icon]) {
case 'html icon.svg':
monitor.classList.add('html-svg-monitor-fill');
break;

case 'css icon.svg':
monitor.classList.add('css-svg-monitor-fill');
break;

case 'javascript icon.svg':
monitor.classList.add('javascript-svg-monitor-fill');
break;

case 'python icon.svg':
monitor.classList.add('python-svg-monitor-fill');
monitorLeg.classList.add('python-svg-leg-fill');
break;

case 'svelte icon.svg':
monitor.classList.add('svelte-svg-monitor-fill');
monitorBody.classList.add('svelte-svg-body-fill');
monitorLeg.classList.add('svelte-svg-leg-fill');
break;

case 'github icon.svg':
monitor.classList.add('github-svg-monitor-fill');
break;

default:
break;
}
Still feels a bit too much but I think that's the smallest I can get the code to be. It would be amazing if I can somehow do this in CSS before I close this @MarkBoots, in regards to your comment. Could this be done with css?
MarkBoots
MarkBoots2y ago
are monitor-body and monitor-leg childs of monitor? because in that case
const monitor = document.querySelector(".monitor");
const languageIcons = [ "html", "css", "javascript", "python", "svelte", "github" ];

for(let i = 0; i < languageIcons.length; i++ ){
monitor.dataset.icon = languageIcons[i];
await(2000)
}
const monitor = document.querySelector(".monitor");
const languageIcons = [ "html", "css", "javascript", "python", "svelte", "github" ];

for(let i = 0; i < languageIcons.length; i++ ){
monitor.dataset.icon = languageIcons[i];
await(2000)
}
.monitor[data-icon="html"]{ fill: #123456 }
.monitor[data-icon="css"]{ fill: #123456 }
.monitor[data-icon="javascript"]{ fill: #123456 }

.monitor[data-icon="python"]{ fill: #123456 }
.monitor[data-icon="python"]>.monitor-leg { fill: #123456 }

.monitor[data-icon="svelte"]{ fill: #123456 }
.monitor[data-icon="github"]{ fill: #123456 }
.monitor[data-icon="html"]{ fill: #123456 }
.monitor[data-icon="css"]{ fill: #123456 }
.monitor[data-icon="javascript"]{ fill: #123456 }

.monitor[data-icon="python"]{ fill: #123456 }
.monitor[data-icon="python"]>.monitor-leg { fill: #123456 }

.monitor[data-icon="svelte"]{ fill: #123456 }
.monitor[data-icon="github"]{ fill: #123456 }
if you use a data attribute instead of class, there is no need to remove previous values, it will just override
NazCodeland
NazCodelandOP2y ago
<svg width="40" height="40" viewBox="0 0 125 116" fill="none" xmlns="http://www.w3.org/2000/svg">
<path class="monitor" d="M0 13C0 5.8203 5.8203 0 13 0H112C119.18 0 125 5.8203 125 13V70C125 77.1797 119.18 83 112 83H13C5.82029 83 0 77.1797 0 70V13Z" fill="#145883"/>
<path d="M13 13H111V71H13V13Z" fill="white"/>
<image class="language-icon" href="" height="45" width="45" x="45" y="19"/>
<path d="M13.875 45.6932V41.6932L29.875 34.6477V39.25L18.9205 43.6477L19.0682 43.4091V43.9773L18.9205 43.7386L29.875 48.1364V52.7386L13.875 45.6932Z" fill="black"/>
<path d="M44.8182 28.6364L37.3182 56.5H33.1477L40.6477 28.6364H44.8182Z" fill="black"/>
<path d="M108.531 45.6932L92.5312 52.7386V48.1364L103.486 43.7386L103.338 43.9773V43.4091L103.486 43.6477L92.5312 39.25V34.6477L108.531 41.6932V45.6932Z" fill="black"/>
<path class="monitor-body" d="M53 83H73V101H53V83Z" fill="#D9D9D9"/>
<path class="monitor-leg" d="M35 108.5C35 104.358 38.3579 101 42.5 101H84.5C88.6421 101 92 104.358 92 108.5C92 112.642 88.6421 116 84.5 116H42.5C38.3579 116 35 112.642 35 108.5Z" fill="#D9D9D9"/>
</svg>
<svg width="40" height="40" viewBox="0 0 125 116" fill="none" xmlns="http://www.w3.org/2000/svg">
<path class="monitor" d="M0 13C0 5.8203 5.8203 0 13 0H112C119.18 0 125 5.8203 125 13V70C125 77.1797 119.18 83 112 83H13C5.82029 83 0 77.1797 0 70V13Z" fill="#145883"/>
<path d="M13 13H111V71H13V13Z" fill="white"/>
<image class="language-icon" href="" height="45" width="45" x="45" y="19"/>
<path d="M13.875 45.6932V41.6932L29.875 34.6477V39.25L18.9205 43.6477L19.0682 43.4091V43.9773L18.9205 43.7386L29.875 48.1364V52.7386L13.875 45.6932Z" fill="black"/>
<path d="M44.8182 28.6364L37.3182 56.5H33.1477L40.6477 28.6364H44.8182Z" fill="black"/>
<path d="M108.531 45.6932L92.5312 52.7386V48.1364L103.486 43.7386L103.338 43.9773V43.4091L103.486 43.6477L92.5312 39.25V34.6477L108.531 41.6932V45.6932Z" fill="black"/>
<path class="monitor-body" d="M53 83H73V101H53V83Z" fill="#D9D9D9"/>
<path class="monitor-leg" d="M35 108.5C35 104.358 38.3579 101 42.5 101H84.5C88.6421 101 92 104.358 92 108.5C92 112.642 88.6421 116 84.5 116H42.5C38.3579 116 35 112.642 35 108.5Z" fill="#D9D9D9"/>
</svg>
@MarkBoots monitor-body, monitor-leg are not childs of monitor I can try still, incase it might work even if they are children of monitor. Awesome to know that data attributes don't need to be removed
MarkBoots
MarkBoots2y ago
you can make it a group <g> and add the class to that
NazCodeland
NazCodelandOP2y ago
ok, gonna look into that hmm, reading up on <g> on MDN, the example they show is targeting the same path of the SVG, so in my case, I'm not sure if I can target different paths by targeting the <g>
NazCodeland
NazCodelandOP2y ago
NazCodeland
NazCodelandOP2y ago
do you think it's possible to achieve that with the <g>? it's not always the path with the class of "monitor" that's changing color, on python and svelte svg's the body/leg also change https://jenkov.com/tutorials/svg/g-element.html don't think it would work in my case good to know about it though, thank you for the help!
Want results from more Discord servers?
Add your server