Code für einen einfachen JavaScript-Countdown-Timer?


147

Ich möchte einen einfachen Countdown-Timer verwenden, der 30 Sekunden nach dem Ausführen der Funktion beginnt und bei 0 endet. Keine Millisekunden. Wie kann es codiert werden?

Antworten:


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
}

Um den Code für den Timer in einem Absatz (oder an einer anderen Stelle auf der Seite) anzuzeigen, geben Sie einfach die folgende Zeile ein:

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

wo die Sekunden erscheinen sollen. Fügen Sie dann die folgende Zeile in Ihre timer()Funktion ein, damit sie so aussieht:

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

 document.getElementById("timer").innerHTML=count + " secs"; // watch for spelling
}

Danke für die Antwort. Ich habe Schwierigkeiten, es zu verwenden, weil mein Timer in einem Absatz erscheint. Wie kann ich die 30, 29, 28 usw. in die Mitte eines Absatzes setzen?
Mike

1
Ich habe meine Antwort bearbeitet, um Ihnen zu zeigen, wie der Timer im Absatz
angezeigt wird

2
In der Mitte eines Absatzes (horizontal): <p id = "timer" style = "text-align: center"> </ p>
Alsciende

Klicken Sie auf, Ihr Timer zeigt nur "0 Sekunden" an. Sie sollten das innerHTML-Update nach der Dekrementierung einfügen, nicht im Endfall.
Alsciende

1
Hallo, wie kann ich den Timer beim Laden der Seite stoppen und stattdessen nur, wenn eine Taste gedrückt wird? Wie kann ich den Timer zurücksetzen, wenn eine Taste gedrückt wird, nachdem der Timer bereits abgelaufen ist?
Crmepham

104

Ich habe dieses Skript vor einiger Zeit geschrieben:

Verwendung:

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);
  };
}

1
Ich würde dies gerne anstelle der anderen verwenden. Als ich feststeckte, um die Startnummer neu zu starten, sehe ich, dass dies gut funktioniert.
Oki Erie Rinaldi

Wie mache ich das, wenn ich den Timer zufällig anhalten muss?
SIJ

@ SiJ myCounter.stop();
R3tep

54

Bisher scheinen die Antworten darauf zu beruhen, dass Code sofort ausgeführt wird. Wenn Sie einen Timer für 1000 ms einstellen, liegt dieser tatsächlich bei 1008.

So sollten Sie es machen:

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
}

Rufen Sie zur Verwendung auf:

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
Genau richtig, wie Sie sagten, das ist der einzige Weg, es richtig zu machen!
Mcella

3
Ich gab ihm einen Daumen hoch, mit einer Einschränkung - zu Anzeigezwecken möchten Sie wahrscheinlich die Decke (Math.ceil ()) anstelle des Bodens zeigen. Es ist wirklich verwirrend, wenn die Uhr 0 Sekunden vor dem Auslösen des Alarms 0 erreicht. (Dann muss es natürlich einen zusätzlichen Aufruf geben, um update () vor complete () zu aktualisieren)
Paul Williams

21

Hier ist eine andere, wenn jemand eine für Minuten und Sekunden braucht:

    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);
    }

Sie sollten keine Zeichenfolge an den ersten Parameter von setTimeout übergeben, setTimeout(Decrement, 1000)wird bevorzugt. stackoverflow.com/questions/6232574/…
Scottux

Vielen Dank für den Vorschlag, ich habe das Skript aktualisiert.
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>


8
Dieses Skript verwendet sehr schlechte Praktiken aus den 90er Jahren. Und auch 1,5 Stunden sind keine 2 Stunden. Es ist 1 Stunde 30 Minuten. Sie sollten verwenden Math.floor, nichtMath.round
Corbacho

3

Gerade geändert @ ClickUpvote Antwort :

Sie können IIFE (Sofort aufgerufener Funktionsausdruck) und Rekursion verwenden, um es ein bisschen einfacher zu machen:

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


2

Wenn Sie die akzeptierte Antwort erweitern, wird Ihr Computer möglicherweise in den Ruhezustand versetzt usw. Der Timer funktioniert möglicherweise nicht mehr. Sie können eine echte Zeit auf Kosten einer kleinen Verarbeitung erhalten. Dies gibt eine echte verbleibende Zeit.

<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

Mit reinem JS können Sie wie folgt vorgehen. Sie müssen der Funktion nur die Anzahl der Sekunden mitteilen, und der Rest wird erledigt.

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>


0

Basierend auf der von @Layton Everson vorgestellten Lösung habe ich einen Zähler entwickelt, der Stunden, Minuten und Sekunden enthält:

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);
}

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>


0

Meine Lösung arbeitet mit MySQL-Datums- und Uhrzeitformaten und bietet eine Rückruffunktion. auf Komplement. Haftungsausschluss: funktioniert nur mit Minuten und Sekunden, da dies das ist, was ich brauchte.

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})

0

Aus Gründen der Leistung können wir jetzt requestAnimationFrame sicher für schnelle Schleifen anstelle von setInterval / setTimeout verwenden.

Wenn bei Verwendung von setInterval / setTimeout eine Schleifenaufgabe mehr Zeit als das Intervall benötigt, erweitert der Browser einfach die Intervallschleife, um das vollständige Rendern fortzusetzen. Dies schafft Probleme. Nach Minuten der Überlastung von setInterval / setTimeout kann dies die Registerkarte, den Browser oder den gesamten Computer einfrieren.

Internetgeräte bieten ein breites Leistungsspektrum, so dass es unmöglich ist, eine feste Intervallzeit in Millisekunden fest zu codieren!

Verwenden Sie das Date-Objekt , um die Startdatumsepoche mit der aktuellen zu vergleichen. Das ist viel schneller als alles andere, der Browser um alles kümmern wird, bei einer konstanten 60FPS (1000-1060 = 16.66ms Frame ) - ein Viertel eines Lidschlag - und wenn die Aufgabe in der Schleife , die mehr als das Der Browser lässt einige Repaints fallen.

Dies ermöglicht einen Spielraum, bevor unsere Augen es bemerken ( Mensch = 24FPS => 1000/24 ​​= 41,66 ms pro Frame = flüssige Animation!)

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>

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.