William C
William C

Reputation: 55

How can I update many properties of an element without listing them individually in JavaScript?

Is there anyway I can reduce this code? I already tried shortening it to the shortest I can possibly think. Is there any possible shortening techniques there is?

document.getElementById('switcher').addEventListener('click', (param1) => {
    let dmbody = document.body.style;
    let dmbutton = document.getElementById('switcher').style;
    if(param1.target.value == "Off"){
        param1.target.value = "On";
        param1.target.textContent = "Dark";
        dmbody.backgroundColor = "var(--darkbg-color)";
        dmbody.color = "var(--darktxtcolor)";
        dmbutton.backgroundColor = "var(--darkbg-color)";
        dmbutton.color = "var(--darktxtcolor)";
        dmbutton.setProperty("border", "1px solid #FFF");
    } else {
        param1.target.value = "Off";
        param1.target.textContent = "Light";
        dmbody.backgroundColor = "var(--lightbg-color)";
        dmbody.color = "var(--lighttxtcolor)";
        dmbutton.backgroundColor = "var(--lightbg-color)";
        dmbutton.color = "var(--lighttxtcolor)";
        dmbutton.setProperty("border", "1px solid #000");
    }
})
<button id="switcher" value="Off">Light</button>

Upvotes: 3

Views: 104

Answers (2)

Cerbrus
Cerbrus

Reputation: 72857

Use CSS to style your elements for each "theme", then just set the theme class on the body:

document.getElementById('switcher').addEventListener('click', (param1) => {
  let isDark = param1.target.value === "Off";

  document.body.classList.toggle('dark', isDark);
  param1.target.value = isDark ? "On" : "Off";
  param1.target.textContent = isDark ? "Dark" : "Light";
})
body {
  --lightbg-color: #FFF;
  --lighttxtcolor: #000;
  --darkbg-color: #111;
  --darktxtcolor: #EEE;

  background-color: var(--lightbg-color);
  color: var(--lighttxtcolor);
}

#switcher {
  background-color: var(--lightbg-color);
  color: var(--lighttxtcolor);
  border: 1px solid #000;
}

body.dark {
  background-color: var(--darkbg-color);
  color: var(--darktxtcolor);
}

body.dark #switcher {
  background-color: var(--darkbg-color);
  color: var(--darktxtcolor);
  border: 1px solid #FFF;
}
<button id="switcher" value="Off">Light</button>

Or, if you want to do it extra fancy, you can use the "theme" class on the body to switch css variable values:

document.getElementById('switcher').addEventListener('click', (param1) => {
  let isDark = param1.target.value === "Off";

  document.body.classList.toggle('dark', isDark);
  param1.target.value = isDark ? "On" : "Off";
  param1.target.textContent = isDark ? "Dark" : "Light";
})
body {
  --bg-color: #FFF;
  --txt-color: #000;
  --border-color: #000;
}

body.dark {
  --bg-color: #111;
  --txt-color: #EEE;
  --border-color: #EEE;
}

body {
  background-color: var(--bg-color);
  color: var(--txt-color);
}

#switcher {
  background-color: var(--bg-color);
  color: var(--txt-color);
  border: 1px solid var(--border-color);
}
<button id="switcher" value="Off">Light</button>

Upvotes: 8

Lu&#237;s Mestre
Lu&#237;s Mestre

Reputation: 1938

One way you could reduce your code would be to isolate the validation of the current target value, and that value in each of the changes separately.

Also to simplify I created the color variable to help minimize the refactoring of the backgroundColor and color changes

document.getElementById('switcher').addEventListener('click', (param1) => {
    let dmbody = document.body.style;
    let dmbutton = document.getElementById('switcher').style;
    let isOff = param1.target.value == "Off";
    let color = isOff ? "dark" : "light";

    param1.target.value = isOff ? "On" : "Off";
    param1.target.textContent = isOff ? "Dark" : "Light";
    dmbody.backgroundColor = `var(--${color}bg-color)`;
    dmbody.color = `var(--${color}txtcolor)`;
    dmbutton.backgroundColor = `var(--${color}bg-color)`;
    dmbutton.color = `var(--${color}txtcolor)`;
    dmbutton.setProperty("border", `1px solid ${isOff ? "#FFF" : "#000"}`);
})

Although this is a refactor way of doing it, I would still prefer @Cerbrus answer

Upvotes: 1

Related Questions