javascripthtmlcsstypescript

Toggle from light to dark move using slider is not working


Please see my code below. I am trying just to get my existing slider to toggle between light and dark mode. I am using typescript, HTML, and CSS. I was easily able to get this to work with a button, but I am trying to do it with a slider.

I have tried to use the .checked attribute, just the eventlistener as well as a boolean to detect whether the page is currently dark or light. I have seemingly tried everything, in addition to talking to chatgpt. Nothing seemed to work. I would appreciate any help here.

Please see all code below.

const themeStyle = document.getElementById('theme-style');

// Detect if slider has been toggled on or off
const sliderToggle = document.getElementById('toggle-switch') //as HTMLInputElement;

// Show message when general button is interacted
function showMessage() {
  console.log("showMessage function called");
  const message = "Hello, TypeScript!";
  alert(message);
}

// Button interaction for general button
const button = document.getElementById("general-button");

function generalButtonSetUp() {
  if (button) {
    button.addEventListener("click", showMessage);
  }
}

// Switch for theme change
function themeSwitchSetUp() {
  let body = document.body;
  if (sliderToggle) {
    sliderToggle.addEventListener('change', () => {
      if (sliderToggle.checked) {
        body.classList.add('light-theme');
      } else {
        body.classList.remove('light-theme');
      }
    });
  }
}

// Check for element existence before attaching event listeners
document.addEventListener("DOMContentLoaded", () => {
  generalButtonSetUp();
  themeSwitchSetUp();
});
body {
  background-color: #333333;
  color: #ffffff;
}

.light-theme {
  background-color: #ffffff;
  color: #000000;
}

.switch {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 34px;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  -webkit-transition: .4s;
  transition: .4s;
}

.slider:before {
  position: absolute;
  content: "";
  height: 26px;
  width: 26px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  -webkit-transition: .4s;
  transition: .4s;
}

input:checked + .slider {
  background-color: #2196F3;
}

input:focus + .slider {
  box-shadow: 0 0 1px #2196F3;
}

input:checked+.slider:before {
  -webkit-transform: translateX(26px);
  -ms-transform: translateX(26px);
  transform: translateX(26px);
}

.slider.round {
  border-radius: 34px;
}

.slider.round:before {
  border-radius: 50%;
}
<body>
  <h1>Welcome to My TypeScript Webpage</h1>
  <p>This is a basic webpage using TypeScript.</p>

  <label id="toggle-switch" class="switch">
            <input type="checkbox">
            <span class="slider round"></span>
        </label>

  <button id="general-button">General Button</button>

  <script src="dist/app.js"></script>
</body>


Solution

  • The issue is with your sliderToggle. To make your code work; you need addEventListener on input rather than toggle-switch label. Something like:

    const themeStyle = document.getElementById('theme-style');
    
    // Detect if slider has been toggled on or off
    const sliderToggle = document.querySelector('#toggle-switch input')
    // ^^^^^^^^^^Notice this
    
    // Show message when general button is interacted
    function showMessage() {
      console.log("showMessage function called");
      const message = "Hello, TypeScript!";
      alert(message);
    }
    
    // Button interaction for general button
    const button = document.getElementById("general-button");
    
    function generalButtonSetUp() {
      if (button) {
        button.addEventListener("click", showMessage);
      }
    }
    
    // Switch for theme change
    function themeSwitchSetUp() {
      let body = document.body;
      if (sliderToggle) {
        sliderToggle.addEventListener('change', () => {
          if (sliderToggle.checked) {
            body.classList.add('light-theme');
          } else {
            body.classList.remove('light-theme');
          }
        });
      }
    }
    
    // Check for element existence before attaching event listeners
    document.addEventListener("DOMContentLoaded", () => {
      generalButtonSetUp();
      themeSwitchSetUp();
    });
    body {
      background-color: #333333;
      color: #ffffff;
    }
    
    .light-theme {
      background-color: #ffffff;
      color: #000000;
    }
    
    .switch {
      position: relative;
      display: inline-block;
      width: 60px;
      height: 34px;
    }
    
    .switch input {
      opacity: 0;
      width: 0;
      height: 0;
    }
    
    .slider {
      position: absolute;
      cursor: pointer;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: #ccc;
      -webkit-transition: .4s;
      transition: .4s;
    }
    
    .slider:before {
      position: absolute;
      content: "";
      height: 26px;
      width: 26px;
      left: 4px;
      bottom: 4px;
      background-color: white;
      -webkit-transition: .4s;
      transition: .4s;
    }
    
    input:checked+.slider {
      background-color: #2196F3;
    }
    
    input:focus+.slider {
      box-shadow: 0 0 1px #2196F3;
    }
    
    input:checked+.slider:before {
      -webkit-transform: translateX(26px);
      -ms-transform: translateX(26px);
      transform: translateX(26px);
    }
    
    .slider.round {
      border-radius: 34px;
    }
    
    .slider.round:before {
      border-radius: 50%;
    }
    <body>
      <h1>Welcome to My TypeScript Webpage</h1>
      <p>This is a basic webpage using TypeScript.</p>
    
      <label id="toggle-switch" class="switch">
                <input type="checkbox">
                <span class="slider round"></span>
            </label>
    
      <button id="general-button">General Button</button>
    
      <script src="dist/app.js"></script>
    </body>