User picks two colors - background and text. When user press 'apply' div changes. But I want the themes to be seperate, like two themes are working at once: one for background, second for text. So there's 4 themes options and 2 of them must be selected. But only one at the time is applied! I know this explanation is blurry so please check the example on jsfiddle: http://jsfiddle.net/7Lysdwzo/2/ try it and then comment the second line in function saveTheme: setTheme(theme2); . Only one aspect changes every time.
code:
<div>
<div id="choose"></div>
<div >
<button onclick="theme1='light';showChosen()" title="Light mode">
light
</button>
<button onclick="theme1='dark';showChosen()" title="Dark mode">
dark
</button>
<br/>
<button onclick="theme2='Blue';showChosen()" title="Blue">
Blue
</button>
<button onclick="theme2='Green';showChosen()" title="Green">
Green
</button>
</div>
<div style="height:100px;width:100px"> div </div>
</div>
:root,
:root.light {
--bg-color: #fff;
}
:root.dark {
--bg-color: #121212;
}
button:checked {
border:1px solid red;
}
:root,
:root.Blue {
--text-color: blue;
}
:root.Green {
--text-color: green;
}
.div1,.div2 {
background-color: var(--bg-color);
color: var(--text-color)
}
const setTheme = theme => document.documentElement.className = theme;
var theme1="";
var theme2="";
function saveTheme() {
setTheme(theme1);
setTheme(theme2);
}
function showChosen() {
var str = 'background should be: ' theme1 ';;; text should be: ' theme2 '<button onclick="saveTheme()" title="Green"> apply</button>';
document.getElementById("choose").innerHTML = str;
}
Is there a way to use two themes at once, one for one aspect, and the other for other aspect?
CodePudding user response:
You can use classList.add and classList.remove instead of replacing the whole className.
const setTheme = theme => document.documentElement.classList.add(theme);
var theme1="";
var theme2="";
function saveTheme() {
// remove all the themes that the user could have added before
document.documentElement.classList.remove("light", "dark", "Blue", "Green");
setTheme(theme1);
setTheme(theme2);
}
CodePudding user response:
You don't have to use classes. You can use data-attributes to store each type and just use a single event handler to look for the class to determine what to do.
function setTheme(el,theme,type){
el.setAttribute("data-" type,theme);
}
let target = document.querySelector(".div1");
document.body.addEventListener("click",function(e){
let btn = e.target;
if(btn.classList.contains("setTheme")){
target.setAttribute("data-" btn.dataset.type,btn.dataset.theme);
var str = 'background should be: ' (target.dataset.bg || "") ';;; text should be: ' (target.dataset.text || "") '<button title="Green"> apply</button>';
document.getElementById("choose").innerHTML = str;
}
else if(btn.classList.contains("saveTheme")){
console.log("save")
}
});
:root,
[data-bg="theme1"] {
--bg-color: #fff;
}
[data-bg="theme2"] {
--bg-color: #121212;
}
button:checked {
border:1px solid red;
}
:root,
[data-text="blue"]{
--text-color: blue;
}
[data-text="green"]{
--text-color: green;
}
.div1,.div2 {
background-color: var(--bg-color);
color: var(--text-color)
}
<div>
<div id="choose"></div>
<div >
<button data-type="bg" data-theme="theme1" title="Light mode">
light
</button>
<button data-type="bg" data-theme="theme2" title="Dark mode">
dark
</button>
<br/>
<button data-type="text" data-theme="blue" title="Blue">
Blue
</button>
<button data-type="text" data-theme="green" title="Green">
Green
</button>
</div>
<div style="height:100px;width:100px"> div </div>
</div>