What are the steps to pause and restart my countdown timer?

I'm attempting to create a countdown timer with the following 4 functionalities:

  1. Change button to 'stop' when 'start' is clicked
  2. Stop the timer when 'stop' is clicked
  3. Show the 'start' button when the timer is stopped
  4. Reset the timer when 'reset' is clicked

$(document).ready(function() {
  var counter = 0;
  var timeleft = 5;

  function nf(num) {
    var s = '0' + num;
    return s.slice(-2);
  }

  function convertSeconds(s) {
    var min = Math.floor(s / 60);
    var sec = s % 60;
    return nf(min, 2) + ' ' + nf(sec, 2);
  }

  function setup() {
    var timer = document.getElementById("timer");
    timer.innerHTML = (convertSeconds(timeleft - counter));

    var interval = setInterval(timeIt, 1000);

    function timeIt() {
      counter++;
      timer.innerHTML = (convertSeconds(timeleft - counter));
      if (counter == timeleft) {
        clearInterval(interval);
      }
    }
  }
  $("#timer-button").click(function() {
    setup();
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Answer №1

I also found myself in need of something similar recently. To address this, I took the approach of creating an ES6 class to handle the functionality.
In my implementation, I utilized Events to communicate with other components regarding the timer state. Here is a fiddle that aligns with your requirements, although I've retained my EventManager() calls to showcase my actual process.
I made use of this particular EventManager. By default, the timer increments in 100ms intervals, but you have the flexibility to adjust this by invoking startTimer() with your desired interval value.

class Timer {
  constructor(maxTime, startValue = 0) {
    // Current timer value in tenths of a second
    this.value = startValue;
    // Maximum duration for the timer in seconds
    this.maxTime = maxTime * 10;
    this.timerRunning = false;
  }

  /**
   * Initiates the timer. Increments the timer value every specified interval.
   * @param {number} interval in ms
   */
  startTimer(interval = 100) {
    if (!this.timerRunning) {
      let parent = this;
      this.timerPointer = setInterval(function() {
        if (parent.value < parent.maxTime) {
          parent.value++;
          //EventManager.fire('timerUpdated');
          $("span").text(parent.value / 10 + "/" + parent.maxTime / 10);
        } else {
          parent.stopTimer();
          //EventManager.fire('timeExceeded');
          $("button").text("Start");
          this.resetTimer();
          $("span").text("Countdown over");
        }
      }, interval);
      this.timerRunning = true;
    }
  }

  // Halts the Timer.
  stopTimer() {
    clearInterval(this.timerPointer);
    this.timerRunning = false;
  }

  // Resets the timer and stops it.
  resetTimer() {
    this.stopTimer();
    this.value = 0;
    $("span").text("0/" + this.maxTime/10);
    //EventManager.fire('timerUpdated');
  }

  // Resets the timer and initiates from the beginning.
  restartTimer() {
    this.resetTimer();
    this.startTimer();
  }
}

let timer = new Timer(6);
$("#start-stop").click(function() {
  if (timer.timerRunning) {
    timer.stopTimer();
    $("#start-stop").text("Start");
  } else {
    timer.startTimer();
    $("#start-stop").text("Stop");
  }
});
$("#reset").click(function() {
  timer.resetTimer();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="start-stop">
Start
</button>
<button id="reset">
Reset
</button>
<span>Timer: </span>

Answer №2

const divEl = document.querySelector('div');
const startBtn = document.querySelector('#timerBtn');
const resetBtn = document.querySelector('#reset');

let startFlag = 0;
let count = 0;
let intervalId;
const ms = 1000;

divEl.textContent = count;

startBtn.addEventListener('click', function() {
    startFlag = startFlag + 1;

    if(startFlag%2 !== 0) { // Start button clicked;
        startBtn.textContent = 'Stop';
        startTimer();
    } else {
        startBtn.textContent = 'Start';
        stopTimer();
    }
});

resetBtn.addEventListener('click', function() {
    count = 0;
    divEl.textContent = count;
});

function startTimer() {
    intervalId = setInterval(() => {
        count = count + 1;
        divEl.textContent = count;
    }, 1000);
}

function stopTimer() {
    clearInterval(intervalId);
}
<div></div>
<button id="timerBtn">Start</button>
<button id="reset">Reset</button>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The Ajax call is failing to trigger the success function

Can anyone assist me? My success function isn't working properly. The beforesend is functioning correctly and I've verified the variable s. It has a true value before the ajax call, so all validations are correct. Please take a look... function ...

Tips for preserving the state of the Material-UI AutoComplete during component re-renders?

Currently, I am utilizing the Material-UI v4 AutoComplete component along with the renderOption prop in order to display a checkbox item option. The issue arises when the onChange event occurs and updates a hook in the parent component causing a re-rende ...

Incorporating Button Value from Anchor Tag Title Upon Page Load

Currently, I am working on a real estate project and facing an issue with a contact modal box. My goal is to extract the title from tag "a" and place it as the button value in the modal box. English isn't my strong suit, so please excuse any errors i ...

Retrieve an array from the success function of a jQuery AJAX call

After successfully reading an rss file using the jQuery ajax function, I created the array function mycarousel_itemList in which I stored items by pushing them. However, when I tried to use this array in another function that I had created, I encountered t ...

Retrieve the variance between two arrays and store the additions in AddedList and the removals in RemovedList using typescript

I am still getting the hang of Typescript and I am trying to figure out the best solution for my issue. I have two arrays, A and B, and I need to identify the difference between them in relation to array A. The goal is to separate the elements that were ad ...

What is the best way to use pattern matching to specifically match IDs while ensuring that the variable number aligns without needing to manually code every potential option?

I have recently acquainted myself with Jquery selectors and they are proving to be very useful. The issue I am facing currently is that all of my variable names follow similar patterns of starting and ending. The IDs are generated from elsewhere, and I am ...

Replacing the tbody element in React with centered text using inline styles ---If you want

I am working with an empty array in React that I translate into state. When the array is empty, I want to insert a text that says "no match events yet..." into a react-bootstrap Table's tbody. In the current setup, I am struggling to center the text ...

PayPal users have the option to adjust the price of their purchase prior to final

Currently facing a minor issue with my website. I am trying to allow users to customize certain options before checking out, which would impact the final price. While I have successfully implemented this feature, users can easily inspect element and modify ...

What is the best way to align a TabPanel component at the center using React Material UI

As I attempt to compile a list of articles while switching to a list of other entities in React + material UI, I have encountered some difficulties. Specifically, I am struggling to center the Card displaying an article in alignment with the centered Tabs. ...

What is the best way to move between websites or pages without having to reload the current page using a selector?

Have you ever wondered how to create a webpage where users can navigate to other websites or pages without seeing their address, simply by selecting from a drop-down menu? Take a look at this example. Another similar example can be found here. When visit ...

using a variable object to load, access data, and handle errors through mutations

element, I have incorporated two distinct mutations in a single react component: const [get_items, { error, loading, data }] = useMutation(GET_ITEMS); const [add_to_cart] = useMutation(ADD_TO_CART); To streamline and access both components' error, ...

Troubleshooting ng-click not functioning within ng-repeat with database integration in MEAN Stack

//app.js var blogApp = angular.module('BlogApp', []); blogApp.controller('BlogController', function($scope, $http){ $scope.createPost = createPost; $scope.deletePost = deletePost; function init(){ getAllPosts(); } init(); ...

The following MongoDB errors unexpectedly popped up: MongoNetworkError: connect ETIMEDOUT and MongoServerSelectionError: connect ETIMEDOUT

I've been working on a React and NextJS App for about a month now, utilizing MongoDB as my database through MongoDB Atlas. I'm currently using the free version of MongoDB Atlas. For the backend, I rely on NextJS's api folder. Everything wa ...

What are the advantages of using Yarn instead of NPM? Understanding the distinctions between the two package managers

What sets Yarn apart from NPM? I've been scouring the internet for articles that compare Yarn and NPM, but all I find are resources detailing the equivalent commands between the two. While both seem to offer similar functionalities, such as local cac ...

Exploring Nashorn's capabilities in parsing TypeScript

Recently, I came across a discussion suggesting that Nashorn in JDK 9 should have the capability to parse TypeScript. Excited to try it out, I attempted to use it like this: Parser parser = Parser.create(); CompilationUnitTree ...

Show only half of the Google Charts

I have a code snippet that displays a chart with dimensions of 500x500. However, I only want to show half of the chart, like 500x250. But whenever I adjust the values in the div, it resizes the entire chart instead of just showing half. My goal is to hide ...

Determine whether all elements in the array are false using Array.every()

Below is an example of an array: myArray = {firstValue: false, secondValue: false, thirdValue: true, forthValue: false}; The goal is to determine if every value in the array is false. If that condition is met, then perform a specific action. For instance ...

When running the `npm run dev` command, Tailwind does not seem to function

I have been given a task to create forms using tailwindcss, but when I try to run `npm run build`, it doesn't work. Can anyone assist me with this? npm ERR! code ELIFECYCLE npm ERR! errno 9 npm ERR! <a href="/cdn-cgi/l/email-protection" class="__cf ...

Fetch information from DataObject's CSV file using JavaScript

After reading a csv file with the following code: var x="dema.csv"; loadCSV(x); function loadCSV(file) { if (window.XMLHttpRequest) { // IE7+, Firefox, Chrome, Opera, Safari var request = new XMLHttpRequest(); } else { // ...

What is the best way to style output in jQuery for a specific div?

I have developed a tool for creating forms, but I am struggling to format the output neatly like pretty print. I have tried using \n and pre tags as well. allCont += "<label>"+insCleaned+"</label><input type='text' name= ...