Home > OS >  Can't create a simple light switch with Javascript
Can't create a simple light switch with Javascript

Time:08-13

I'm trying to make a simple light switch. My code turns off lights on first click but doesn't turn it back on on second click. The problem is that my check variable is always false and I don't know why that is.

I was able to make a light switch with classList.toggle. But I still want to know why my code doesn't work.

Can someone please explain why variable "check" is always false in my code?

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Button</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <div >
      <button >LIGHTS ON</button>
    </div>
    <script src="script.js"></script>
  </body>
</html>

CSS

* {
  margin: 0;
  padding: 0;
}

body {
  background: #333;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.btn {
  padding: 30px 100px;
  font-size: 30px;
  font-family: monospace;
  text-shadow: 1px 1px 1px #eee, -1px -1px 3px #333;

  background-color: orange;
  border: none;

  box-shadow: 0 0 3px 2px orange, 0 0 20px orange;

  cursor: pointer;

  transition: all 0.1s;
}

.btn:active {
  transform: scale(0.97);
  box-shadow: 0 0 3px 2px orange, 0 0 10px orange;
}

.clickedClass {
  background-color: rgb(30, 30, 30) !important;
  color: #eee !important;
  text-shadow: 0 0 6px #eee !important;
  box-shadow: none !important;
}

JS

'use strict';

const btn = document.querySelector('.btn');
const clickedClass = document.querySelector('.clickedClass');
const check = btn.classList.contains('clikedClass');

function clicked() {
  if (!check) {
    btn.classList.add('clickedClass');
    btn.textContent = `LIGHTS OFF`;

    console.log(`${check}`);
  } else {
    btn.classList.remove('clickedClass');
    btn.textContent = `LIGHTS ON`;
    
    console.log(`${check}`);
  }
}

btn.addEventListener('click', clicked);

CodePudding user response:

The problem is that you access the class list initially and never check it after

const check = btn.classList.contains('clikedClass');

You should do this inside your event handler

function clicked() {
    const check = btn.classList.contains('clikedClass');
    if (!check) {

    ...
}

EDIT

I provide a working codepen of your code here : https://codepen.io/aSH-uncover/pen/yLKReWp

You will never believe what the problem was... :D

Carefully read the two lines of code below and you will find it :D (and this is the perfect opportunity to learn about the usage of constant rather than free strings)

const check = btn.classList.contains('clikedClass');

btn.classList.add('clickedClass');

CodePudding user response:

From the above comment ...

"Why does the OP want to script a button element when the expected behavior can be achieved without JS by an adequately styled checkbox control ... <input type="checkbox"/>?"

body {
  margin: 0;
  padding: 5px;
}
[data-lightswitch] {
  position: relative;
  display: block;
  margin: 0 10px 10px 10px;
}
[data-lightswitch] > [type="checkbox"] {
  position: absolute;
  left: 10px;
  top: 10px;
  z-index: -1;
}
[data-lightswitch] > [data-light-on],
[data-lightswitch] > [data-light-off] { 
/* OP's styling rules */
  padding: 30px 100px;
  font-size: 30px;
  font-family: monospace;
  text-shadow: 1px 1px 1px #eee, -1px -1px 3px #333;

  background-color: orange;
  border: none;

  box-shadow: 0 0 3px 2px orange, 0 0 20px orange;

  cursor: pointer;

  transition: all 0.1s;
}

[data-lightswitch] > [type="checkbox"] ~ [data-light-on],
[data-lightswitch] > [type="checkbox"]:checked  ~ [data-light-off] {
  display: none;
}
[data-lightswitch] > [type="checkbox"] ~ [data-light-off],
[data-lightswitch] > [type="checkbox"]:checked ~ [data-light-on] {
  display: inline-block;
}
[data-lightswitch] > [type="checkbox"]:focus ~ [data-light-on],
[data-lightswitch] > [type="checkbox"]:focus ~ [data-light-off] {
  outline: 3px dotted black;
}

[data-lightswitch] > [type="checkbox"]:checked ~ [data-light-on] {
/* OP's styling rules */
  background-color: rgb(30, 30, 30) !important;
  color: #eee !important;
  text-shadow: 0 0 6px #eee !important;
  box-shadow: none !important;
  transform: scale(0.97);
  box-shadow: 0 0 3px 2px orange, 0 0 10px orange;
}
<label data-lightswitch>
  <input type="checkbox" />
  <span data-light-on>Light off</span>
  <span data-light-off>Light on</span>
</label>

<label data-lightswitch>
  <input type="checkbox" />
  <span data-light-on>Off</span>
  <span data-light-off>On</span>
</label>

  • Related