I am learning how to create websites. I want to build a simple theme switcher with HTML/CSS/JavaScript. I've done the theme switching part, but I want to change the picture in the button when I press it.
Here is my moon picture: (https://www.svgrepo.com/svg/6390/moon) and here is my sun picture: (https://www.svgrepo.com/svg/304624/sun-light-theme).
Here is my code:
const btn = document.querySelector('.btn_theme');
btn.addEventListener('click', function() {
document.body.classList.toggle('dark_theme');
});
body {
background-color: white;
color: black;
font-family: "Trebuchet MS", Helvetica, sans-serif;
font-size: 16pt;
font-weight: normal;
}
body.dark_theme {
background-color: #2F3136;
color: white;
font-size: 16pt;
font-weight: normal;
font-family: "Trebuchet MS", Helvetica, sans-serif;
}
.container {
width: 100px;
height: 55px;
background-color: #2F3136;
color: white;
text-align: center;
border-radius: 10px;
position: absolute;
display: flex;
align-items: center;
}
.btn_theme {
text-align: center;
width: 90px;
height: 45px;
background-color: white;
margin: 0;
padding: 0;
border: 0;
left: 5px;
border-radius: 8px;
position: relative;
transition: all .15s linear;
-webkit-transition: all .15s linear;
-moz-transition: all .15s linear;
align-items: center;
}
button:hover {
background-color: #2f3647;
transition: all 0.15s linear;
-webkit-transition: all 0.15s linear;
-moz-transition: all 0.15s linear;
}
<p>text</p>
<div >
<button id="btn_theme"><img src="../imgs/солнце.svg" /></button>
</div>
CodePudding user response:
There are a couple ways to accomplish this.
One way is to just get rid of the img tag and change the button's background image.
const btn = document.querySelector('.btn_theme');
btn.addEventListener('click', function() {
document.body.classList.toggle('dark_theme');
});
.btn_theme {
background: url('https://www.svgrepo.com/show/304624/sun-light-theme.svg');
text-align: center;
width: 40px;
height: 40px;
background-color: white;
margin: 0;
padding: 0;
border: 0;
left: 5px;
border-radius: 8px;
position: relative;
transition: all .15s linear;
-webkit-transition: all .15s linear;
-moz-transition: all .15s linear;
align-items: center;
}
button:hover {
background-color: #2f3647;
transition: all 0.15s linear;
-webkit-transition: all 0.15s linear;
-moz-transition: all 0.15s linear;
}
.dark_theme {
background: #ffaaff
}
.dark_theme .btn_theme {
background: url('https://www.svgrepo.com/show/6390/moon.svg');
}
<button id="btn_theme"></button>
Another solution is to use a data-attribute to store the current state and change the img tag's src value.
const btn = document.querySelector('.btn_theme');
const icon = btn.querySelector('img');
btn.addEventListener('click', function() {
document.body.classList.toggle('dark_theme');
if (icon.dataset.theme == "light") {
icon.dataset.theme = "dark";
icon.src = "https://www.svgrepo.com/show/6390/moon.svg";
} else {
icon.dataset.theme = "light";
icon.src = "https://www.svgrepo.com/show/304624/sun-light-theme.svg";
}
});
.btn_theme {
text-align: center;
width: 40px;
height: 40px;
background-color: white;
margin: 0;
padding: 0;
border: 0;
left: 5px;
border-radius: 8px;
position: relative;
transition: all .15s linear;
-webkit-transition: all .15s linear;
-moz-transition: all .15s linear;
align-items: center;
}
button:hover {
background-color: #2f3647;
transition: all 0.15s linear;
-webkit-transition: all 0.15s linear;
-moz-transition: all 0.15s linear;
}
.dark_theme {
background: #ffaaff
}
<button id="btn_theme"><img data-theme="light" src="https://www.svgrepo.com/show/304624/sun-light-theme.svg"></button>
CodePudding user response:
You need to update the src
attribute of your image using setAttribute()
.
You could use modular arithmetic to switch between pictures. This would work for however many pictures you want to have. It is however not required for a two images as you could just use a boolean. Nevertheless here how you could do it using modulo operation.
// All the pictures we want to switch between
const pics = [
"https://dummyimage.com/50x50/000/fff",
"https://dummyimage.com/50x50/dddddd/000",
// "https://dummyimage.com/50x50/d420d4/000" // comment this out for a third pic
]
let curPicIdx = 0;
window.addEventListener("DOMContentLoaded", e => {
// when the page has loaded set the first picture
const button = document.getElementById("mybutton");
const img = document.getElementById("myimage");
img.setAttribute("src", pics[curPicIdx])
// whenever we click on the button change the picture to the next one
button.addEventListener("click", e => {
// calculate the index of the next picture using modular arithmetic
curPicIdx = (curPicIdx 1) % pics.length;
console.log(`Setting pic ${curPicIdx}`);
// set the next picture using the calculated index
img.setAttribute("src", pics[curPicIdx]);
})
})
<button id="mybutton"><img id="myimage"/>
If you want to have three pictures, just add another URL within the array and it will switch between all three pictures.
In general there are a lot of ways to embed images into buttons. You might wanna have a look at this thread.