skip to Main Content

I’ve tried to switch by boolean but for some reason it won’t work.

function onBall3Click() {
    var ball3 = document.querySelector('.ball3')
    
    var isOn = true; 
    
    if ( isOn )
    {
       ball3.style.backgroundColor = 'Yellow'
       ball3.innerText = 'ON'
    }
    else
    {
       ball3.style.backgroundColor = 'Grey'
       ball3.innerText = 'OFF'   
    }
    
    isOn = !isOn
    
    ball3.style.width = ball3Size + 'px';
    ball3.style.height = ball3Size + 'px';
}

I put a boolean with if and else and expected the colors and text to change.

3

Answers


  1. Try changing the if/else statement as follows:

    if (ball3.style.backgroundColor == 'Yellow') {
      // was on
    } else {
      //was off
    }
    
    Login or Signup to reply.
  2. There is no possible scenario in which this condition would ever be false:

    var isOn = true;
    if ( isOn ){
    

    The variable is explicitly defined as true and then immediately tested to see if it’s true. Which it will be.

    It sounds like you want the scope of the variable to be outside the function. For example:

    var isOn = true;
    
    function onBall3Click() {
      var ball3 = document.querySelector('.ball3');
      if (isOn) {
        ball3.style.backgroundColor = 'Yellow';
        ball3.innerText = 'ON';
      } else {
        ball3.style.backgroundColor = 'Grey';
        ball3.innerText = 'OFF';
      }
      isOn = !isOn;
      ball3.style.width = ball3Size + 'px';
      ball3.style.height = ball3Size + 'px';
    }
    

    This way the variable is only defined once, and the same instance of the variable is used each time the function is invoked. Which will allow the current value of the variable to persist after the function completes and be read again the next time the function is called.

    Login or Signup to reply.
  3. You should use data attributes to handle state-keeping.

    Here is an example of a global click listener that checks if the element that you clicked is a ball. If it is a ball, toggle the state of the data attribute using the dataset property.

    The CSS will now control the look of the ball.

    // Could be modified to handle non-binary states
    const getNextState = (state) => {
      switch (state) {
        case 'on':
          return 'off';
        case 'off':
        default:
          return 'on';
      }
    };
    
    const toggleState = (ball) => {
      const currentState = ball.dataset.state ?? 'off';
      ball.dataset.state = getNextState(currentState);
    }
    
    document.addEventListener('click', (e) => {
      if (e.target.classList.contains('ball')) {
        toggleState(e.target);
      }
    });
    html, body { width: 100%; height: 100%; margin: 0; padding: 0; }
    
    body {
      display: flex; justify-content: space-around; align-items: center;
      background: #222;
    }
    
    .ball {
      aspect-ratio: 1; /* Keep width/height a ratio of 1/1 */
      border-radius: 50%;
      background: grey;
      width: 1rem;
      width: attr(data-size rem); /* Experimental */
    }
    
    /* Hard-coded rules */
    .ball[data-size="2"] { width: 2rem; }
    .ball[data-size="3"] { width: 3rem; }
    .ball[data-size="4"] { width: 4rem; }
    
    .ball:hover { cursor: pointer; }
    
    .ball[data-state="on"] { background: yellow; }
    .ball[data-state="off"] { background: grey; }
    <div class="ball" data-size="2"></div>
    <div class="ball" data-size="4"></div>
    <div class="ball" data-size="3"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search