{"id":22345780,"url":"https://github.com/gerhynes/countdown-timer","last_synced_at":"2026-04-19T05:36:52.273Z","repository":{"id":106044681,"uuid":"109870668","full_name":"gerhynes/countdown-timer","owner":"gerhynes","description":"A countdown timer using vanilla JavaScript. Built for Wes Bos' JavaScript 30 course. ","archived":false,"fork":false,"pushed_at":"2018-05-12T19:59:42.000Z","size":6,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-26T10:23:53.607Z","etag":null,"topics":["javascript","javascript30","pomodoro"],"latest_commit_sha":null,"homepage":"https://gk-hynes.github.io/countdown-timer/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gerhynes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-07T17:49:17.000Z","updated_at":"2018-05-12T19:59:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"e6154472-c071-4f7c-8704-a0e38c5d281a","html_url":"https://github.com/gerhynes/countdown-timer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gerhynes/countdown-timer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gerhynes%2Fcountdown-timer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gerhynes%2Fcountdown-timer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gerhynes%2Fcountdown-timer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gerhynes%2Fcountdown-timer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gerhynes","download_url":"https://codeload.github.com/gerhynes/countdown-timer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gerhynes%2Fcountdown-timer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270467648,"owners_count":24588806,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-14T02:00:10.309Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","javascript30","pomodoro"],"created_at":"2024-12-04T09:18:41.430Z","updated_at":"2026-04-19T05:36:52.230Z","avatar_url":"https://github.com/gerhynes.png","language":"JavaScript","readme":"# Countdown Timer\r\n\r\nA countdown timer using vanilla JavaScript. Built for Wes Bos' [JavaScript 30](https://javascript30.com/) course.\r\n\r\n[![Screenshot of Countdown Timer](https://res.cloudinary.com/gerhynes/image/upload/v1519489664/Screenshot-2018-2-24_19_56_tgrsiv.png)](https://gk-hynes.github.io/countdown-timer/)\r\n\r\n## Notes\r\n\r\nThe goal is to create a countdown timer where you can set how long each session is.\r\n\r\nFirst, make a function, `timer`, which takes in the number of seconds left.\r\n\r\nOne way of handling this would be with `setInterval`, but that can stop running if you tab away or scroll.\r\n\r\nInstead, use `Date.now()` to figure out when the timer started.\r\n\r\nCreate a variable, `then`, equal to `now` (counted in milliseconds) and `seconds * 1000`.\r\n\r\nNow you can use `setInterval`, since it doesn't matter if there is a delay and the clock takes a second to show the updated time.\r\n\r\nInside `setInterval` set `secondsLeft` to `then - Date.now()`. Wrap everything in `Math.round()` and divide by 1000 to get the time in seconds.\r\n\r\nStore the interval in a `let` variable, `countdown`.\r\n\r\nUse an if statment to check if `secondsLeft \u003c 0`. If so, call `clearInterval` and pass it `countdown`.\r\n\r\nBut `setInterval` doesn't run immediately. It has to wait for the first second to elapse.\r\n\r\nTo deal with this, create another function, `displayTimeLeft`, which takes in seconds. Run this as soon as `timer` is invoked and then call it again within the `setInterval`.\r\n\r\nInside `displayTimeLeft` convert `seconds` to minutes and seconds.\r\n\r\n```js\r\nconst minutes = Math.floor(seconds / 60);\r\nconst remainderSeconds = seconds % 60;\r\n```\r\n\r\nNow you can start to update the HTML.\r\n\r\n### Display timer\r\n\r\nSelect the `display__time-left` div and assign it to the variable `timerDisplay`.\r\n\r\n```js\r\nconst display = `${minutes}:${remainderSeconds};\r\ntimerDisplay.textContent = display;\r\n```\r\n\r\nHere there is the problem that if there are fewer than 10 seconds left it will display 9 not 09.\r\n\r\nUse a ternary operator to get around this.\r\n\r\n```js\r\nconst display = `${minutes}:${\r\n  remainderSeconds \u003c 10 ? \"0\" : \"\"\r\n}${remainderSeconds}`;\r\n```\r\n\r\nYou can also update the browser tab: `document.title = display;`\r\n\r\n### Display Ending Time\r\n\r\nMake a function, `displayEndTime`, which takes in a timestamp of when you want to finish.\r\n\r\nInside the function turn the timestamp into a date.\r\n\r\n```js\r\nconst end = new Date(timestamp);\r\nconst hour = end.getHours();\r\nconst minutes = end.getMinutes();\r\n```\r\n\r\nSelect the `display__end-time` p tag and assign it to the variable `endTime`.\r\n\r\nUse another ternary operator to ensure it says 09 when there are fewer than 10 minutes on the clock.\r\n\r\n```js\r\nendTime.textContent = `Be Back At ${hour}:${minutes \u003c 10 ? \"0\" : \"\"}${minutes}`;\r\n```\r\n\r\nCall `displayEndTime(then)` inside `timer`.\r\n\r\nThis retuns the time using the 24 hour clock. To display 3pm instead of 15:00, check if the hour is greater than 12 and return `hour - 12`.\r\n\r\n### Connect the Timer to the Buttons\r\n\r\nEach button has a `data-time` attribute with the number of seconds you want to run.\r\n\r\nThere is also a form with a custom number of minutes.\r\n\r\nSelect all the buttons and add event listeners. Listen for a click and run a function, `startTimer`.\r\n\r\nInside `startTimer` convert the buttons' time into a real number using `parseInt()` and then call `timer(seconds)`.\r\n\r\n```js\r\nfunction startTimer() {\r\n  const seconds = parseInt(this.dataset.time);\r\n  timer(seconds);\r\n}\r\n```\r\n\r\nOne problem now is that you can start multiple timers, e.g. by clicking the wrong button, and they'll all run at once.\r\n\r\nSo, whenever you start `timer` use `clearInterval(countdown)`.\r\n\r\nSelect the custom form and listen for a submit action. Run a function against it, calling `e.preventDefault``so it doesn't refresh the page and send the data over a GET request.\r\n\r\nFinally, create a variable `mins` equal to `this.minutes.value`. Call `this.reset()` to clear the input.\r\nPass `mins * 60` to `timer`.\r\n\r\nNow you have a functioning adjustable countdown timer.\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgerhynes%2Fcountdown-timer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgerhynes%2Fcountdown-timer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgerhynes%2Fcountdown-timer/lists"}