Codice per un semplice conto alla rovescia JavaScript?


147

Voglio usare un semplice conto alla rovescia che inizia a 30 secondi da quando la funzione viene eseguita e termina a 0. Nessun millisecondo. Come può essere codificato?

Risposte:


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
}

Per far apparire il codice per il timer in un paragrafo (o in qualsiasi altra parte della pagina), basta inserire la riga:

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

dove vuoi che appaiano i secondi. Quindi inserire la seguente riga nella timer()funzione, in modo che sia simile al seguente:

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

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

Grazie per la risposta. Ho difficoltà ad usarlo perché il mio timer appare in un paragrafo. Come posso mettere 30, 29, 28, ecc. Nel mezzo di un paragrafo?
Mike,

1
Ho modificato la mia risposta per mostrarti come visualizzare il timer nel paragrafo :)
Fai clic per votare il

2
Nel mezzo di un paragrafo (orizzontale): <p id = "timer" style = "text-align: center"> </p>
Alsciende,

Fare clic, il timer visualizzerà solo "0 secondi". Dovresti inserire l'aggiornamento innerHTML dopo la decrementazione, non nel caso finale.
Alsciende,

1
Ciao come posso interrompere il timer in esecuzione sul caricamento della pagina e invece solo quando viene premuto un pulsante? Inoltre, come posso ripristinare il timer quando si preme un pulsante dopo che il timer è già scaduto?
crmepham,

104

Ho scritto questo script qualche tempo fa:

Uso:

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
Mi piacerebbe usare questo invece dell'altro. Quando sono stato bloccato per riavviare il numero iniziale, vedo che sta funzionando bene ..
Oki Erie Rinaldi

Se devo interrompere il timer per caso, come posso farlo?
SIJ,

@SIJ myCounter.stop();
R3tep,

54

Finora le risposte sembrano basarsi sull'esecuzione istantanea del codice. Se si imposta un timer per 1000ms, in realtà sarà invece di circa 1008.

Ecco come dovresti farlo:

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
}

Per usare, chiama:

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
Spot, come hai detto, è l'unico ed unico modo per farlo bene!
forcella

3
Ho dato un pollice in su, con un avvertimento: per scopi di visualizzazione probabilmente vorrai mostrare il soffitto (Math.ceil ()) invece del pavimento. È davvero disorientante quando l'orologio raggiunge 0 un secondo prima che l'allarme si attivi. (Quindi ovviamente ci deve essere una chiamata aggiuntiva per update () prima di complete ())
Paul Williams

21

Eccone un altro se qualcuno ne ha bisogno per minuti e secondi:

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

Non si dovrebbe passare una stringa al primo parametro di setTimeout, setTimeout(Decrement, 1000)si preferisce. stackoverflow.com/questions/6232574/...
Scottux

Grazie per il suggerimento, ho aggiornato la sceneggiatura.
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
Questo script utilizza pratiche pessime degli anni '90. E anche 1,5 ore non sono 2 ore. Sono 1 ora e 30 minuti. Dovresti usare Math.floor, noMath.round
corbacho il

3

Ho appena modificato la risposta di @ ClickUpvote :

Puoi usare IIFE (Espressione di funzione immediatamente invocata ) e ricorsione per renderla un po 'più semplice:

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


2

Espandendosi sulla risposta accettata, la macchina in modalità di sospensione, ecc. Potrebbe ritardare il funzionamento del timer. Puoi ottenere un vero momento, al costo di una piccola elaborazione. Questo darà un vero tempo rimasto.

<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

Puoi fare quanto segue con JS puro. Hai solo bisogno di fornire la funzione con il numero di secondi e farà il resto.

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

Sulla base della soluzione presentata da @Layton Everson, ho sviluppato un contatore che include ore, minuti e secondi:

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

La mia soluzione funziona con i formati di data e ora MySQL e offre una funzione di richiamata. su complimento. Dichiarazione di non responsabilità: funziona solo con minuti e secondi, poiché questo è ciò di cui avevo bisogno.

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

Per motivi di prestazioni, ora possiamo tranquillamente utilizzare requestAnimationFrame per un loop veloce, anziché setInterval / setTimeout.

Quando si utilizza setInterval / setTimeout, se un'attività del ciclo impiega più tempo dell'intervallo, il browser semplicemente estenderà il ciclo dell'intervallo, per continuare il rendering completo. Questo sta creando problemi. Dopo alcuni minuti di sovraccarico setInterval / setTimeout, questo può bloccare la scheda, il browser o l'intero computer.

I dispositivi Internet hanno una vasta gamma di prestazioni, quindi è impossibile codificare un intervallo di tempo fisso in millisecondi!

Utilizzando l' oggetto Date , per confrontare l'Epoca della data di inizio e quella corrente. Questo è molto più veloce di ogni altra cosa, il browser si prenderà cura di tutto, a 60FPS costanti ( 1000/60 = 16.66ms per frame ) - un quarto di un battito di ciglia - e se l'attività nel loop richiede più di questo , il browser rilascerà alcune riduzioni.

Questo ci consente di notare un margine davanti ai nostri occhi ( Human = 24FPS => 1000/24 ​​= 41.66ms per frame = animazione fluida!)

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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.