0

I wanna be able to disable this function using the same button again (click it again), so it would work like a toggle button to start the time counter and to end it whenever i want.

<span id="timer"></span>

<script>
var startTime = Date.now();

function myFunction() {
var interval = setInterval(function() {
    var elapsedtime = Date.now() - startTime;
    var secs = Math.floor(elapsedtime / 1000);
    var minutes = Math.floor(elapsedtime / (1000 * 60));
    var hours = Math.floor(elapsedtime / (1000 * 60 * 60));
    document.getElementById("timer").innerHTML = hours.toFixed(0) + 'h ' + minutes.toFixed(0) + 'm ' + secs.toFixed(0) + 's';
}, 1000);
}
</script>

<button onclick="myFunction()">Click me</button>

Also, in this code, the seconds keeps adding up more than 60, and i want them to reset to 0 whenever the secs counter reaches 60, is that possible?

One more thing, is there a way to record the counted time whenever i stop/toggle off the function?

Im a beginner so i hope you make it simple for me.

Someone Special
  • 12,479
  • 7
  • 45
  • 76
Mido H
  • 51
  • 7
  • Also, notwithstanding the solution below, your time calculations to derive at hh:mm:ss format looks off. And thats why it keeps adding up to more than 59. – GetSet Nov 21 '20 at 02:38

5 Answers5

0

You need to use clearInterval to clear your intervals.

<script>
var startTime = Date.now();
let timerStarted = false; //created a temp variable to know whether interval started.
let interval; // set the interval as a global variable so it can be reset.
function myFunction() {

if (!timerStarted) { //if it's not started, start it
    interval = setInterval(function() { //use the global variable to store the interval
    timerStarted = true; //set it to true so we know it started
    var elapsedtime = Date.now() - startTime;
    var secs = Math.floor(elapsedtime / 1000);
    var minutes = Math.floor(elapsedtime / (1000 * 60));
    var hours = Math.floor(elapsedtime / (1000 * 60 * 60));
    document.getElementById("timer").innerHTML = hours.toFixed(0) + 'h ' + minutes.toFixed(0) + 'm ' + secs.toFixed(0) + 's';
}, 1000);
} else {
  clearInterval(interval) //if it's started, clear the timer.
}
}
</script>

Also, in this code, the seconds keeps adding up more than 60, and i want them to reset to 0 whenever the secs counter reaches 60, is that possible?

It's not a javascript problem in your codes but a mathematical one.

var secs = Math.floor(elapsedtime / 1000);

You want it to reset to 0, then you need to check for number of seconds. E.g. if it's 70 seconds elapsed, I want to remove 60 seconds, with remainder 10 seconds (10 seconds is the value u want).

For this please refer to https://stackoverflow.com/a/41633001/2822041

One more thing, is there a way to record the counted time whenever i stop/toggle off the function?

It's not a problem. You need to use a variable for that too.

For example

let timerCount = 0;

function myFunction() {
   interval = setInterval(() => {
       timerCount++;
       console.log('Elapsed ', timerCount)
   }, 1000)
}
Someone Special
  • 12,479
  • 7
  • 45
  • 76
  • The timer keeps counting even without clicking on the button. For example, if i wait 10 secs and then click on the button, the timer will begin from 00:00:10. – Mido H Nov 21 '20 at 04:44
  • Also, i want to reset it to 00:00:00 and be able to click on the button again to start the function once more not just stop the interval. – Mido H Nov 21 '20 at 04:46
  • then put timerCount inside myFunction, so when you click, you are calling the function myFunction, and the timer will start from 0. – Someone Special Nov 21 '20 at 11:09
0

Once you set a variable with setInterval you can remove it with clearInterval var interval;

function doStuff() {
  var elapsedtime = Date.now() - startTime;
  var secs = Math.floor(elapsedtime / 1000);
  var minutes = Math.floor(elapsedtime / (1000 * 60));
  var hours = Math.floor(elapsedtime / (1000 * 60 * 60));
  document.getElementById("timer").innerHTML = hours.toFixed(0) + 'h ' + 
  minutes.toFixed(0) + 'm ' + secs.toFixed(0) + 's';
}

function toggleStuff() {
  if(!interval) {
    interval = setInterval(doStuff, 1000)
  } else {
    clearInterval(interval)
    interval = null
  }
}
Matthew Moran
  • 1,457
  • 12
  • 22
0

const el = document.querySelector("#timer");
const btn = document.querySelector("#timerBtn");
const padd = (n) => n > 9 ? n : `0${n}`; // Adds a zero padding
let isRun = false; // Boolean to check if Timer is running
let itv = undefined; // Clearable interval reference
let startTime = undefined; // Date object
let timesStarted = 1; // Count runs

function renderButton() {
  btn.textContent = `${isRun? "STOP" : "START"} ${timesStarted}`;
}

function renderTime() {
  const elapsed = Date.now() - startTime || 0,
    s = Math.floor(elapsed / 1000),
    m = Math.floor(elapsed / (1000 * 60)),
    h = Math.floor(elapsed / (1000 * 60 * 60));
  el.textContent = `${h}h ${padd(m)}m ${padd(s)}s`;
};

function start() {
  isRun = true;
  startTime = Date.now();
  itv = setInterval(() => renderTime(), 1000 / 60);
  renderButton();
};

function stop() {
  isRun = false;
  clearInterval(itv);
  timesStarted += 1;
  renderButton();
};

function toggle() {
  isRun ? stop() : start();
  isRun != isRun;
};

btn.addEventListener("click", toggle);
renderButton();
renderTime();
<button id="timerBtn"></button><br>
<span id="timer"></span>
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
0

My way...

(function()  // IIFE
  {
  const theTimmer = document.getElementById('timer')
    ,   theButton = document.getElementById('the-button')
    ,   twoDigits = n => n>9?n:`0${n}`
    ,   one_sec   = 1000
    ,   one_min   = one_sec *60
    ,   one_hour  = one_min *60
    ;
  let interval  = null
    , startTime = null
    , count     = 1
    , onRun     = false
    ;
  theButton.textContent = `Start : 1`
  theButton.onclick=_=>
    {
    if (onRun)
      {
      clearInterval(interval)
      onRun = false
      theButton.textContent = `Start : ${++count}`
      }
    else
      {
      theButton.textContent = `Stop : ${count}`
      onRun     = true
      startTime = Date.now()
      interval  = setInterval(()=>
        {
        let tim = Date.now() -startTime
          , h   = ~~(tim /one_hour)
          , m   = ~~((tim %one_hour) /one_min)
          , s   = ~~((tim %one_min) /one_sec)
          ;
        theTimmer.textContent = `${h}h ${twoDigits(m)}m ${twoDigits(s)}s`
        }
        , 250);
      }
    }  
  })()
<p id="timer"> -- </p>
<button id="the-button">Click me</button>
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
0
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

<script>
// AA: Global variables to hold the number of clicks and the var startTime values...etc;
const secsInMinute = 60;
const minutesInHour = 60;
var numOfClicks = 0;
var startTime;
var interval;
var timerObject = {
    secs : 0, minutes : 0, hours : 0
}
var lastTimerObject = []
var counter = -1;
function displayTimer(){
    // The constant variables 
    const secsInMinute = 60;
    const minutesInHour = 60;
    document.getElementById("timer").innerHTML = timerObject.hours.toFixed(0) + 'h ' + 
    // AA: Subtract the number of elapsed minutesInHour passed from the captured minutes
    (timerObject.minutes - (timerObject.hours * minutesInHour)).toFixed(0)+ 'm ' +
    // AA: Subtract the number of elapsed secsInMinutes passed from the captured seconds
    (timerObject.secs- (timerObject.minutes * secsInMinute)).toFixed(0) + 's';
}
function timer () {


    var elapsedtime = Date.now() - startTime;
    timerObject.secs = Math.floor(elapsedtime / 1000) ;
    timerObject.minutes = Math.floor(elapsedtime / (1000 * 60)) ;
    timerObject.hours = Math.floor(elapsedtime / (1000 * 60 * 60));
    displayTimer();
};

function myFunction() {
    
    // AA: Increment the numOfClicks to determine whether or not to start the timer
    // or to save the timer values and then clear it
    numOfClicks ++;
    // AA: Move the startTime inside myFunction, so it captures the time
    // when the user clicks the button, rather than when the document loads
    startTime = Date.now();
    if (numOfClicks % 2 == 1)// Start the timer
    {
        // AA: Start the timer
        interval = setInterval(timer, 1000);
        document.getElementById("timerBttn").textContent = "Stop Timer";        
    }
    else // Save the timer values and then clear it
    {
        counter++;
        // AA: Clear the timer
        clearInterval(interval);
        // Change the text on the button to Start Timer
        document.getElementById("timerBttn").textContent = "Start Timer";
        // Save the timer values to currentTimer Object and reset the
        // timerObject to zeros.
        lastTimerObject[counter] = {};
        lastTimerObject[counter].secs = timerObject.secs;
        lastTimerObject[counter].minutes = timerObject.minutes; 
        lastTimerObject[counter].hours =timerObject.hours;
        timerObject.secs = 0;
        timerObject.minutes = 0; 
        timerObject.hours = 0;
        displayTimer();
        // AA: The alert is optional, just to display the last timer val before stoppage
        alert ('Current Timer Value: ' + lastTimerObject[counter].hours.toFixed(0) + 'h ' + 
    (lastTimerObject[counter].minutes - (lastTimerObject[counter].hours * minutesInHour)).toFixed(0)+ 'm ' +
    (lastTimerObject[counter].secs- (lastTimerObject[counter].minutes * secsInMinute)).toFixed(0) + 's');    
    
    lastTimerObject[counter].secs = (lastTimerObject[counter].secs- (lastTimerObject[counter].minutes * secsInMinute)).toFixed(0);
    lastTimerObject[counter].minutes = (lastTimerObject[counter].minutes - (lastTimerObject[counter].hours * minutesInHour)).toFixed(0) ;

    // console.log("lastTimerObject.hours " + lastTimerObject[counter].hours + " lastTimerObject.minutes " + lastTimerObject[counter].minutes + " lastTimerObject.secs " + lastTimerObject[counter].secs );
    console.log ("Timer Values:")
    for (var item of lastTimerObject)
    {
        console.log(item.hours + "h " + item.minutes + "m " + item.secs + "s");
    }
    
    }
    
}

</script>

<!--AA: Chnaged the name of the button to indicate start/stop timer to user clearly
and added id to the button to maniplulate the name within the JavaScript-->
<button id="timerBttn" onclick="myFunction()">Start Timer</button>
<span id="timer"></span>
</body>
</html>
Aber Abou-Rahma
  • 174
  • 1
  • 9
  • is it possible to store the time recorded (for each time i use the button) in a separated log? – Mido H Nov 21 '20 at 14:42
  • Edited the post so that the lastTimerObject is array of object and within each click to stop the timer it will add the lastTimerObject to the array. to save them to a log or text the file it will be a bit more work (say you can stringfy the object to json). Reference this article: https://www.websparrow.org/web/how-to-create-and-save-text-file-in-javascript – Aber Abou-Rahma Nov 21 '20 at 16:51