-2

I have created a code that when you select an option in a select to the body of my website includes a new attribute in class with setAttribute, but my problem is that it deletes the other attribute of the dark mode.

The intention of the code is to change some colors of the web site and that it stays saved to the local storage.

What can I change?

function wow(value) { 
 var index = { 
 chb: "griegos", 
 cj: "romanos", 
 hv: "celtas" 
 }; 
 document.getElementById("body").setAttribute("class", index[value]);}
.griegos {background: orange}
.romanos {background: purple}
.celtas {background: green}
<body id="body" class="griegos dark">
<select class="forminput" onchange="wow(this.value)"><option value="chb">Camp Half-Blood</option><option value="cj">Camp Jupiter</option><option value="hv">Hotel Valhalla</option></select></div>
  • 2
    Use the proper dedicated API that exists for such purposes, not setAttribute. https://developer.mozilla.org/en-US/docs/Web/API/Element/classList – CBroe Aug 25 '21 at 14:57
  • 1
    You'll want to both add the new class and remove either of the old ones. `document.body.classList.remove("griegos romanos celtas"); document.body.classList.add(index[value]);` – T.J. Crowder Aug 25 '21 at 15:01

1 Answers1

0

One option is as below; using the Element.classList API:

// ensuring that we look for elements after the document
// is loaded and elements are present, by waiting for
// the 'DOMContentLoaded' event to fire:
window.addEventListener('DOMContentLoaded', () => {
  // named function, which receives the 'evt' 
  // (a reference to the Event Object) passed
  // automatically from the (later) use of
  // EventTarget.addEventListener():
  function wow(evt) {

    var index = {
      chb: "griegos",
      cj: "romanos",
      hv: "celtas"
    };

    // here we look for the relevant element via its
    // id:
    document.getElementById("body")
      // we use Element.classList.remove() to remove
      // previously-chosen class-names:
      .classList.remove(
        // we use an Array-literal with the spread
        // syntax to create an Array of the options
        // within the <select>:
        [...evt.target.options]
          // Array.prototype.map() lets us to return
          // a new Array based on the former Array:
          .map(
            // and here we pass the relevant class-name
            // returned from the index Object based on
            // the current option's value:
            (opt) => index[opt.value]
        )
      );
    // once those class-names are removed, we once again
    // select the relevant element based on its id, and
    // use Element.classList.add() to add the relevant
    // class-name, again from the index Object:
    document.getElementById("body").classList.add(
      index[evt.currentTarget.value]
    );
  }

// here use document.querySelector() to find the <select>
// element using a CSS selector:
document.querySelector('select.forminput')
  // and bind the event-handling using
  // EventTarget.addEventListener(), to bind the wow()
  // function to handle the 'change' event:
  .addEventListener('change', wow);
});
.griegos {
  background: orange
}

.romanos {
  background: purple
}

.celtas {
  background: green
}
<body id="body" class="griegos dark">
  <select class="forminput">
    <option value="chb">Camp Half-Blood</option>
    <option value="cj">Camp Jupiter</option>
    <option value="hv">Hotel Valhalla</option>
  </select>
</body>

JS Fiddle demo

David Thomas
  • 249,100
  • 51
  • 377
  • 410