Home > Blockchain >  Button won't respond when execute the setInterval function
Button won't respond when execute the setInterval function

Time:12-19

I would like to have the second button ( "free five") to keep checking the condition that it would reappear when the number reached 5 again after I clicked it. However, it never showed up again after I pressed it, unless I press the first button.

Game instruction is in the p section.

let birdNum = document.getElementById("birdNum")
let catchBtn = document.getElementById("catch")
let freeBtn = document.getElementById("free")

function catchBird() {
  birdNum.innerHTML  ;

  if (birdNum.innerHTML > 4) {
    freeBtn.classList.add("fadeIn");
    freeBtn.disabled = false;
  }
}

document.getElementById("catch").addEventListener("click", catchBird);

function freeBird() {
  birdNum.innerHTML -= 5;

  setInterval(() => {
    birdNum.innerHTML  ;
  }, 1000);

  if (birdNum.innerHTML <= 4) {
    freeBtn.classList.remove("fadeIn");
    freeBtn.disabled = true;
  }
}

document.getElementById("free").addEventListener("click", freeBird);
#free {
  opacity: 0;
}

#free.fadeIn {
  opacity: 1;
}
<P>
  press "catch one" to catch one bird. <br> press "free five" to free five bird. <br>
  <br> Once you free five birds, they will come back with their kids, one bird per second.
</P>

<span id="birdNum">0</span>
<button id="catch">
catch one
</button>

<button id="free" disabled=t rue>
free five
</button>

CodePudding user response:

Try the following code, see if it works for you:

Edit: I realised your issue, I edited to work now.

So in your code, you were only checking whether or not to make the 'free' button visible once. And you only checked when it was pressed. For example, we are playing your game and get to 6. We press the 'free birds' button and we go down to one and the 'free birds' button disappears. Now the setInterval keeps making the number of birds go up. We get to 5 and the button does not reappear because we are not running any code to make it reappear. In the setInterval, as well as incrementing the counter, we need to check whether or not we can make the 'free birds' button visible again. See the resetInterval() function. In the setInterval's callback, we are now checking whether of not the birds counter is above 5. If the condition returns true, we will show the 'free birds' button.

With the below JS, it should work nicely.

const birdNum = document.getElementById("birdNum");
const catchBtn = document.getElementById("catch");
const freeBtn = document.getElementById("free");

const initialTimeout = 1000;
let timesBirdsFreed = 0;

let intervalId;

function resetInterval(delay) {
  if (delay < 10) delay = 10;

  if (intervalId) clearInterval(intervalId);
  
  intervalId = setInterval(() => {
    birdNum.innerHTML  ;

    // if statement from catch bird function is needed here too
    if (birdNum.innerHTML >= 5) {
      freeBtn.classList.add("fadeIn");
      freeBtn.disabled = false;
    }
  }, delay);
}

function catchBird() {
  birdNum.innerHTML  ;

  if (birdNum.innerHTML >= 5) {
    freeBtn.classList.add("fadeIn");
    freeBtn.disabled = false;
  }
}

catchBtn.addEventListener("click", catchBird);

function freeBird() {
  timesBirdsFreed  ;
  birdNum.innerHTML -= 5;

  resetInterval(initialTimeout/timesBirdsFreed);

  if (birdNum.innerHTML <= 4) {
    freeBtn.classList.remove("fadeIn");
    freeBtn.disabled = true;
  }
}

freeBtn.addEventListener("click", freeBird);
#free {
  opacity: 0;
}

#free.fadeIn {
  opacity: 1;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Bird Game</title>
    <link href="style.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
    <p>press "catch one" to catch one bird. <br> press "free five" to free five bird. <br><br> Once you free five birds, they will come back with their kids, one bird per second.</p>

    <span id="birdNum">0</span>

    <button id="catch">catch one</button>
    <button id="free" disabled=true>free five</button>

    <script src="script.js"></script>
  </body>
</html>

Essentially, it stores the ID returned by the setInterval() method in a variable (intervalId) and uses it in the resetInterval() function to clear the existing instance of setInterval and then create a new one with a smaller delay. This will make the number of birds increase faster as you free more birds and they will increase with even delays between them.

CodePudding user response:

If you need to stop the setInterval you should keep its instance and then call clearInterval(instance)

I'm not sure what you want to achieve but you may get the idea from the this code:

  let intervalInstance;
  function freeBird() {

    birdNum.innerHTML -= 5;

    if (intervalInstance) {
      clearInterval(intervalInstance);
    }
    intervalInstance = setInterval(() => {
      birdNum.innerHTML  ;
    }, 1000);

    if (birdNum.innerHTML <= 4) {
      freeBtn.classList.remove("fadeIn");
      freeBtn.disabled = true;
    }
  }
  • Related