1

I am trying to set a decrementing timer when a user inputs something in an input. However, I am struggling to get it to properly work, when a user writes something new it restarts.

I thought .one would take care of this but apparently not.

function myTimer() {
  var counter = 15;
  var x = window.setInterval(function() {
    counter--;
    if (counter >= 0) {
      span = document.getElementById("timer");
      span.innerHTML = counter;
    }
    if (counter === 0) {
      span.innerHTML = "OUT OF TIME";
      window.clearInterval(x);
    }
  }, 1000);
}

$("#wrapper input").one("change paste keyup", myTimer);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span id="timer">15</span><br>
<div id="wrapper">
  <input class="something" type="text"><br>
  <input class="somethingelse" type="text">
</div>

jsFiddle

4
  • 1
    The issue is because you're attaching the event to two input. Therefore it fires once per element. As such the timer will reset as soon as the second element is interacted with. You either need to create separate timers or check if the timer is already running when the second event fires so it doesn't get reset. Commented Mar 1, 2019 at 11:59
  • "when a user writes something new it restarts" - Not if you write anything in the same input. Why do you have a second input? Commented Mar 1, 2019 at 12:00
  • 1
    you need a global bool variable isCounterRunning and on first line of your function check its value, if it's true return out the function before doing anything, and if it's false, set it to true and then do the rest of your code in your function. Commented Mar 1, 2019 at 12:06
  • so you want to start the timer whenever the user starts writing in any of these inputs. right? Commented Mar 1, 2019 at 12:09

3 Answers 3

3

Move the counter and test the tId:

var counter = 15, x, span = document.getElementById("timer");

function myTimer() {
  if (!x) x = window.setInterval(function() {
    if (counter === 0) window.clearInterval(x);
    counter--;
    span.innerHTML = counter >= 0 ? counter : "OUT OF TIME"
  }, 1000);
}

$("#wrapper input").one("change paste keyup", myTimer);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span id="timer">15</span><br>
<div id="wrapper">
  <input class="something" type="text"><br>
  <input class="somethingelse" type="text">
</div>

Sign up to request clarification or add additional context in comments.

Comments

2

You need a global bool variable isCounterRunning. On first line of your function check its value, if it's true return out the function before doing anything, and if it's false, set it to true and then do the rest of the code in your function.

var isCounterOn = false
function myTimer() {
  if(isCounterOn) return;
  else{
    isCounterOn = true
    var counter = 15;
    var x = window.setInterval(function() {
      counter--;
      if (counter >= 0) {
        span = document.getElementById("timer");
        span.innerHTML = counter;
      }
      if (counter === 0) {
        span.innerHTML = "OUT OF TIME";
        window.clearInterval(x);
      }
    }, 1000);
  }
}

$("#wrapper input").one("change paste keyup", myTimer);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span id="timer">15</span><br>
<div id="wrapper">
  <input class="something" type="text"><br>
  <input class="somethingelse" type="text">
</div>

2 Comments

Why not use the intervalId, see my answer
@mplungjan yeah i think that's a better way to do it.
1

you have to initialize x outside startInterval so it can be overwritten subsequentially. Moreover, one() will do, as the name says, only one event trigger. If you want to catch everytime an event happens, use on()

var counter = 15;
var x = 0;
var span = document.getElementById("timer");

function myTimer() {
  window.clearInterval(x);
  startInterval();
}

function startInterval() {
  counter = 15;
  span.innerHTML = counter;
  x = setInterval(function() {
    counter--;
    if (counter >= 0) {
      span.innerHTML = counter;
    }
    if (counter === 0) {
      span.innerHTML = "OUT OF TIME";
      window.clearInterval(x);
    }
  }, 1000);
}
$("#wrapper input").on("change paste keyup", myTimer);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span id="timer">15</span><br>
<div id="wrapper">
  <input class="something" type="text"><br>
  <input class="somethingelse" type="text">
</div>

3 Comments

He does not. He only wants it to trigger once
The OP Question is ambiguous: '...when a user writes something new it restarts.' appears to be everytime
The problem was that every time the user types, it restarts

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.