Код для простого таймера обратного отсчета JavaScript?

147

Я хочу использовать простой таймер обратного отсчета, начиная с 30 секунд с момента запуска функции и заканчивая на 0. Нет миллисекунд. Как это можно закодировать?

Майк
источник

Ответы:

255
var count=30;

var counter=setInterval(timer, 1000); //1000 will  run it every 1 second

function timer()
{
  count=count-1;
  if (count <= 0)
  {
     clearInterval(counter);
     //counter ended, do something here
     return;
  }

  //Do code for showing the number of seconds here
}

Чтобы код таймера появился в абзаце (или где-либо еще на странице), просто поместите строку:

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

где вы хотите, чтобы появились секунды. Затем вставьте следующую строку в вашу timer()функцию, чтобы она выглядела следующим образом:

function timer()
{
  count=count-1;
  if (count <= 0)
  {
     clearInterval(counter);
     return;
  }

 document.getElementById("timer").innerHTML=count + " secs"; // watch for spelling
}
Нажмите Upvote
источник
Спасибо за ответ. У меня возникли трудности с его использованием, потому что мой таймер отображается в абзаце. Как я могу поставить 30, 29, 28 и т. Д. В середине абзаца?
Майк
1
Я отредактировал свой ответ, чтобы показать вам, как отображать таймер в абзаце :)
Нажмите Upvote
2
В середине абзаца (по горизонтали): <p id = "timer" style = "text-align: center"> </ p>
Alsciende
Нажмите, ваш таймер будет отображать только «0 секунд». Вы должны поместить обновление innerHTML после декремента, а не в конце.
Alsciende
1
Привет, как я могу остановить работу таймера при загрузке страницы и только при нажатии кнопки? Кроме того, как я могу сделать это сброс таймера, когда кнопка нажата после того, как таймер уже истек?
crmepham
104

Я написал этот сценарий некоторое время назад:

Использование:

var myCounter = new Countdown({  
    seconds:5,  // number of seconds to count down
    onUpdateStatus: function(sec){console.log(sec);}, // callback for each second
    onCounterEnd: function(){ alert('counter ended!');} // final action
});

myCounter.start();

function Countdown(options) {
  var timer,
  instance = this,
  seconds = options.seconds || 10,
  updateStatus = options.onUpdateStatus || function () {},
  counterEnd = options.onCounterEnd || function () {};

  function decrementCounter() {
    updateStatus(seconds);
    if (seconds === 0) {
      counterEnd();
      instance.stop();
    }
    seconds--;
  }

  this.start = function () {
    clearInterval(timer);
    timer = 0;
    seconds = options.seconds;
    timer = setInterval(decrementCounter, 1000);
  };

  this.stop = function () {
    clearInterval(timer);
  };
}
CMS
источник
1
Я хотел бы использовать это вместо другого. Когда я застрял, чтобы перезапустить стартовый номер, я вижу, что это работает хорошо ..
Оки Эри Ринальди
Если мне нужно случайно остановить таймер, как мне это сделать?
SIJ
@SIJ myCounter.stop();
R3tep
54

Пока что ответы, похоже, основаны на том, что код запускается мгновенно. Если вы установите таймер на 1000 мс, вместо этого он будет около 1008.

Вот как вы должны это сделать:

function timer(time,update,complete) {
    var start = new Date().getTime();
    var interval = setInterval(function() {
        var now = time-(new Date().getTime()-start);
        if( now <= 0) {
            clearInterval(interval);
            complete();
        }
        else update(Math.floor(now/1000));
    },100); // the smaller this number, the more accurate the timer will be
}

Чтобы использовать, позвоните:

timer(
    5000, // milliseconds
    function(timeleft) { // called every step to update the visible countdown
        document.getElementById('timer').innerHTML = timeleft+" second(s)";
    },
    function() { // what to do after
        alert("Timer complete!");
    }
);
Ницца Темный Абсол
источник
2
Обратите внимание, как вы сказали, это единственный способ сделать это правильно!
mcella
3
Я дал ему большие пальцы, с одной оговоркой - для целей отображения вы, вероятно, хотите показать потолок (Math.ceil ()) вместо пола. Это действительно сбивает с толку, когда часы достигают 0 секунд, прежде чем сработает сигнал тревоги. (Затем, конечно, необходимо выполнить дополнительный вызов update () перед завершением ())
Пол Уильямс,
21

Вот еще один, если кому-то нужен на минуты и секунды:

    var mins = 10;  //Set the number of minutes you need
    var secs = mins * 60;
    var currentSeconds = 0;
    var currentMinutes = 0;
    /* 
     * The following line has been commented out due to a suggestion left in the comments. The line below it has not been tested. 
     * setTimeout('Decrement()',1000);
     */
    setTimeout(Decrement,1000); 

    function Decrement() {
        currentMinutes = Math.floor(secs / 60);
        currentSeconds = secs % 60;
        if(currentSeconds <= 9) currentSeconds = "0" + currentSeconds;
        secs--;
        document.getElementById("timerText").innerHTML = currentMinutes + ":" + currentSeconds; //Set the element id you need the time put into.
        if(secs !== -1) setTimeout('Decrement()',1000);
    }
Лейтон Эверсон
источник
Не следует передавать строку первому параметру setTimeout, setTimeout(Decrement, 1000)предпочтительно. stackoverflow.com/questions/6232574/…
Scottux
Спасибо за предложение, я обновил скрипт.
Лейтон Эверсон
3

// Javascript Countdown
// Version 1.01 6/7/07 (1/20/2000)
// by TDavid at http://www.tdscripts.com/
var now = new Date();
var theevent = new Date("Sep 29 2007 00:00:01");
var seconds = (theevent - now) / 1000;
var minutes = seconds / 60;
var hours = minutes / 60;
var days = hours / 24;
ID = window.setTimeout("update();", 1000);

function update() {
  now = new Date();
  seconds = (theevent - now) / 1000;
  seconds = Math.round(seconds);
  minutes = seconds / 60;
  minutes = Math.round(minutes);
  hours = minutes / 60;
  hours = Math.round(hours);
  days = hours / 24;
  days = Math.round(days);
  document.form1.days.value = days;
  document.form1.hours.value = hours;
  document.form1.minutes.value = minutes;
  document.form1.seconds.value = seconds;
  ID = window.setTimeout("update();", 1000);
}
<p><font face="Arial" size="3">Countdown To January 31, 2000, at 12:00: </font>
</p>
<form name="form1">
  <p>Days
    <input type="text" name="days" value="0" size="3">Hours
    <input type="text" name="hours" value="0" size="4">Minutes
    <input type="text" name="minutes" value="0" size="7">Seconds
    <input type="text" name="seconds" value="0" size="7">
  </p>
</form>

Kedarnath
источник
8
Этот сценарий использует очень плохие практики 90-х годов. А также 1,5 часа - это не 2 часа. Это 1 час 30 минут. Вы должны использовать Math.floor, а неMath.round
Corbacho
3

Только что изменил ответ @ ClickUpvote :

Вы можете использовать IIFE (выражение для немедленного вызова функции) и рекурсию, чтобы сделать его немного проще:

var i = 5;  //set the countdown
(function timer(){
    if (--i < 0) return;
    setTimeout(function(){
        console.log(i + ' secs');  //do stuff here
        timer();
    }, 1000);
})();

Рохит Шарма
источник
2

В зависимости от принятого ответа, ваша машина перейдет в спящий режим и т. Д., Что может привести к задержке работы таймера. Вы можете получить точное время за небольшую обработку. Это даст истинное время, оставшееся.

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

<script>
var now = new Date();
var timeup = now.setSeconds(now.getSeconds() + 30);
//var timeup = now.setHours(now.getHours() + 1);

var counter = setInterval(timer, 1000);

function timer() {
  now = new Date();
  count = Math.round((timeup - now)/1000);
  if (now > timeup) {
      window.location = "/logout"; //or somethin'
      clearInterval(counter);
      return;
  }
  var seconds = Math.floor((count%60));
  var minutes = Math.floor((count/60) % 60);
  document.getElementById("timer").innerHTML = minutes + ":" + seconds;
}
</script>
Патрик Нотт
источник
0

Вы можете сделать следующее с чистым JS. Вам просто нужно указать функцию с количеством секунд, а все остальное она сделает.

var insertZero = n => n < 10 ? "0"+n : ""+n,
   displayTime = n => n ? time.textContent = insertZero(~~(n/3600)%3600) + ":" +
                                             insertZero(~~(n/60)%60) + ":" +
                                             insertZero(n%60)
                        : time.textContent = "IGNITION..!",
 countDownFrom = n => (displayTime(n), setTimeout(_ => n ? sid = countDownFrom(--n)
                                                         : displayTime(n), 1000)),
           sid;
countDownFrom(3610);
setTimeout(_ => clearTimeout(sid),20005);
<div id="time"></div>

Redu
источник
0

На основе решения, представленного @Layton Everson, я разработал счетчик, включающий часы, минуты и секунды:

var initialSecs = 86400;
var currentSecs = initialSecs;

setTimeout(decrement,1000); 

function decrement() {
   var displayedSecs = currentSecs % 60;
   var displayedMin = Math.floor(currentSecs / 60) % 60;
   var displayedHrs = Math.floor(currentSecs / 60 /60);

    if(displayedMin <= 9) displayedMin = "0" + displayedMin;
    if(displayedSecs <= 9) displayedSecs = "0" + displayedSecs;
    currentSecs--;
    document.getElementById("timerText").innerHTML = displayedHrs + ":" + displayedMin + ":" + displayedSecs;
    if(currentSecs !== -1) setTimeout(decrement,1000);
}
Aiwatko
источник
0

// Javascript Countdown
// Version 1.01 6/7/07 (1/20/2000)
// by TDavid at http://www.tdscripts.com/
var now = new Date();
var theevent = new Date("Nov 13 2017 22:05:01");
var seconds = (theevent - now) / 1000;
var minutes = seconds / 60;
var hours = minutes / 60;
var days = hours / 24;
ID = window.setTimeout("update();", 1000);

function update() {
  now = new Date();
  seconds = (theevent - now) / 1000;
  seconds = Math.round(seconds);
  minutes = seconds / 60;
  minutes = Math.round(minutes);
  hours = minutes / 60;
  hours = Math.round(hours);
  days = hours / 24;
  days = Math.round(days);
  document.form1.days.value = days;
  document.form1.hours.value = hours;
  document.form1.minutes.value = minutes;
  document.form1.seconds.value = seconds;
  ID = window.setTimeout("update();", 1000);
}
<p><font face="Arial" size="3">Countdown To January 31, 2000, at 12:00: </font>
</p>
<form name="form1">
  <p>Days
    <input type="text" name="days" value="0" size="3">Hours
    <input type="text" name="hours" value="0" size="4">Minutes
    <input type="text" name="minutes" value="0" size="7">Seconds
    <input type="text" name="seconds" value="0" size="7">
  </p>
</form>

maztt
источник
0

Мое решение работает с форматами даты и времени MySQL и предоставляет функцию обратного вызова. на завершении. Отказ от ответственности: работает только с минутами и секундами, так как это то, что мне было нужно.

jQuery.fn.countDownTimer = function(futureDate, callback){
    if(!futureDate){
        throw 'Invalid date!';
    }

    var currentTs = +new Date();
    var futureDateTs = +new Date(futureDate);

    if(futureDateTs <= currentTs){
        throw 'Invalid date!';
    }


    var diff = Math.round((futureDateTs - currentTs) / 1000);
    var that = this;

    (function countdownLoop(){
        // Get hours/minutes from timestamp
        var m = Math.floor(diff % 3600 / 60);
        var s = Math.floor(diff % 3600 % 60);
        var text = zeroPad(m, 2) + ':' + zeroPad(s, 2);

        $(that).text(text);

        if(diff <= 0){
            typeof callback === 'function' ? callback.call(that) : void(0);
            return;
        }

        diff--;
        setTimeout(countdownLoop, 1000);
    })();

    function zeroPad(num, places) {
      var zero = places - num.toString().length + 1;
      return Array(+(zero > 0 && zero)).join("0") + num;
    }
}

// $('.heading').countDownTimer('2018-04-02 16:00:59', function(){ // on complete})
nikksan
источник
0

Ради производительности теперь мы можем безопасно использовать requestAnimationFrame для быстрого зацикливания вместо setInterval / setTimeout.

При использовании setInterval / setTimeout, если задача цикла занимает больше времени, чем интервал, браузер просто расширит цикл интервала, чтобы продолжить полный рендеринг. Это создает проблемы. После нескольких минут перегрузки setInterval / setTimeout это может привести к зависанию вкладки, браузера или всего компьютера.

Интернет-устройства имеют широкий диапазон характеристик, поэтому жестко закодировать фиксированный интервал времени в миллисекундах совершенно невозможно!

Используя объект Date , сравнить начальную эпоху даты и текущую. Это намного быстрее, чем все остальное, браузер позаботится обо всем, с постоянной скоростью 60 кадров в секунду ( 1000/60 = 16,66 мс по кадру ) - четверть моргания глаз - и если задача в цикле требует больше, чем это , браузер сбросит некоторые перерисовки.

Это позволяет получить запас на глазах у нас на глаза ( Человек = 24FPS => 1000/24 ​​= 41,66 мс по кадрам = плавная анимация!)

https://caniuse.com/#search=requestAnimationFrame

/* Seconds to (STRING)HH:MM:SS.MS ------------------------*/
/* This time format is compatible with FFMPEG ------------*/
function secToTimer(sec){
  const o = new Date(0), p =  new Date(sec * 1000)
  return new Date(p.getTime()-o.getTime()).toString().split(" ")[4] + "." + p.getMilliseconds()
}

/* Countdown loop ----------------------------------------*/
let job, origin = new Date().getTime()
const timer = () => {
  job = requestAnimationFrame(timer)
  OUT.textContent = secToTimer((new Date().getTime() - origin) / 1000)
}

/* Start looping -----------------------------------------*/
requestAnimationFrame(timer)

/* Stop looping ------------------------------------------*/
// cancelAnimationFrame(job)

/* Reset the start date ----------------------------------*/
// origin = new Date().getTime()
span {font-size:4rem}
<span id="OUT"></span>
<br>
<button onclick="origin = new Date().getTime()">RESET</button>
<button onclick="requestAnimationFrame(timer)">RESTART</button>
<button onclick="cancelAnimationFrame(job)">STOP</button>

NVRM
источник