Kod prostego licznika czasu JavaScript?

147

Chcę użyć prostego licznika czasu, zaczynając od 30 sekund od uruchomienia funkcji i kończąc na 0. Żadnych milisekund. Jak można to zakodować?

Mikrofon
źródło

Odpowiedzi:

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
}

Aby kod licznika czasu pojawił się w akapicie (lub w dowolnym innym miejscu na stronie), po prostu umieść wiersz:

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

gdzie chcesz, aby pojawiły się sekundy. Następnie wstaw następujący wiersz do swojej timer()funkcji, tak aby wyglądał tak:

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

 document.getElementById("timer").innerHTML=count + " secs"; // watch for spelling
}
Kliknij opcję Głos za
źródło
Dziękuję za odpowiedź. Mam trudności z używaniem go, ponieważ mój licznik czasu pojawia się w akapicie. Jak mogę umieścić 30, 29, 28 itd. Na środku akapitu?
Mike
1
Zredagowałem moją odpowiedź, aby pokazać, jak wyświetlić licznik czasu w akapicie :)
Kliknij „Upvote”
2
W środku akapitu (poziomo): <p id = "timer" style = "text-align: center"> </p>
Alsciende,
Kliknij, Twój licznik czasu wyświetli tylko „0 sekund”. Należy umieścić aktualizację innerHTML po dekrementacji, a nie na końcu.
Alsciende
1
Cześć, jak mogę zatrzymać licznik czasu podczas ładowania strony, a zamiast tego tylko po naciśnięciu przycisku? Jak również mogę zresetować licznik czasu, gdy zostanie naciśnięty przycisk, gdy licznik już się wyczerpał?
crmepham
104

Jakiś czas temu napisałem ten skrypt:

Stosowanie:

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
źródło
1
Bardzo chciałbym użyć tego zamiast innych. Kiedy utknąłem, aby ponownie uruchomić numer startowy, widzę, że to działa dobrze ..
Oki Erie Rinaldi.
Jeśli przypadkiem muszę zatrzymać licznik czasu, jak mam to zrobić?
SIJ
@SIJ myCounter.stop();
R3tep
54

Jak dotąd odpowiedzi wydają się polegać na natychmiastowym uruchomieniu kodu. Jeśli ustawisz licznik czasu na 1000 ms, zamiast tego będzie to około 1008.

Oto jak powinieneś to zrobić:

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
}

Aby skorzystać, zadzwoń:

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!");
    }
);
Niet the Dark Absol
źródło
2
Jak powiedziałeś, jest to jedyny sposób, aby zrobić to dobrze!
mcella
3
Złożyłem kciuki w górę, z jednym zastrzeżeniem - do celów wyświetlania prawdopodobnie chcesz pokazać sufit (Math.ceil ()) zamiast podłogi. To naprawdę dezorientujące, gdy zegar osiąga 0 na sekundę przed uruchomieniem alarmu. (Wtedy oczywiście konieczne jest dodatkowe wywołanie update () przed zakończeniem ())
Paul Williams,
21

Oto kolejny, jeśli ktoś potrzebuje go na minuty i sekundy:

    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);
    }
Layton Everson
źródło
Nie należy przekazywać ciągu do pierwszego parametru setTimeout, setTimeout(Decrement, 1000)jest preferowane. stackoverflow.com/questions/6232574/…
Scottux
Dziękuję za sugestię, zaktualizowałem skrypt.
Layton Everson
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
źródło
8
Ten skrypt wykorzystuje bardzo złe praktyki z lat 90-tych. A także 1,5 godziny to nie 2 godziny. To 1 godzina 30 minut. Powinieneś używać Math.floor, nieMath.round
corbacho,
3

Właśnie zmodyfikowana odpowiedź @ ClickUpvote :

Możesz użyć IIFE (natychmiastowo wywoływanego wyrażenia funkcyjnego) i rekurencji, aby było to nieco łatwiejsze:

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

Rohit Sharma
źródło
2

Rozszerzenie po zaakceptowanej odpowiedzi, uśpienie urządzenia itp. Może opóźnić działanie timera. Możesz uzyskać prawdziwy czas, kosztem niewielkiej obróbki. To da prawdziwy czas.

<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>
Patrick Knott
źródło
0

Możesz wykonać następujące czynności z czystym JS. Wystarczy podać funkcji liczbę sekund, a ona zajmie się resztą.

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
źródło
0

Na podstawie rozwiązania przedstawionego przez @Layton Everson stworzyłem licznik godzin, minut i sekund:

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
źródło
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
źródło
0

Moje rozwiązanie działa z formatami daty i godziny MySQL i zapewnia funkcję zwrotną. po skompletowaniu. Zastrzeżenie: działa tylko z minutami i sekundami, ponieważ tego potrzebowałem.

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
źródło
0

Ze względu na wydajność możemy teraz bezpiecznie używać requestAnimationFrame do szybkiego zapętlania zamiast setInterval / setTimeout.

Podczas korzystania z setInterval / setTimeout, jeśli zadanie pętli zajmuje więcej czasu niż interwał, przeglądarka po prostu przedłuży pętlę interwału, aby kontynuować pełne renderowanie. To stwarza problemy. Po minutach przeciążenia setInterval / setTimeout może to spowodować zawieszenie karty, przeglądarki lub całego komputera.

Urządzenia internetowe mają szeroki zakres wydajności, więc niemożliwe jest zaprogramowanie na stałe ustalonego przedziału czasu w milisekundach!

Za pomocą obiektu Date można porównać początkową epokę dat i bieżącą. Jest to o wiele szybsze niż wszystko inne, przeglądarka zajmie się wszystkim ze stałą prędkością 60 klatek na sekundę ( 1000/60 = 16,66 ms na klatkę ) - ćwierć mrugnięcia okiem - i jeśli zadanie w pętli wymaga więcej , przeglądarka upuści kilka przemalowań.

Pozwala to na zachowanie marginesu przed naszymi oczami ( człowiek = 24 kl./s => 1000/24 ​​= 41,66 ms na klatkę = płynna animacja!)

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
źródło