Code pour un compte à rebours JavaScript simple?


147

Je veux utiliser un compte à rebours simple commençant à 30 secondes à partir du moment où la fonction est exécutée et se terminant à 0. Pas de millisecondes. Comment peut-il être codé?

Réponses:


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
}

Pour faire apparaître le code du minuteur dans un paragraphe (ou n'importe où ailleurs sur la page), il suffit de mettre la ligne:

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

où vous voulez que les secondes apparaissent. Insérez ensuite la ligne suivante dans votre timer()fonction, pour qu'elle ressemble à ceci:

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

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

Merci d'avoir répondu. J'ai du mal à l'utiliser car mon minuteur apparaît dans un paragraphe. Comment puis-je mettre les 30, 29, 28, etc. au milieu d'un paragraphe?
Mike

1
J'ai modifié ma réponse pour vous montrer comment afficher le minuteur dans le paragraphe :)
Cliquez sur Upvote le

2
Au milieu d'un paragraphe (horizontalement): <p id = "timer" style = "text-align: center"> </p>
Alsciende

Cliquez, votre minuterie n'affichera que "0 secondes". Vous devez mettre la mise à jour innerHTML après la décrémentation, pas dans le cas final.
Alsciende

1
Salut, comment puis-je arrêter le chronomètre lors du chargement de la page et à la place uniquement lorsqu'un bouton est enfoncé? Comment puis-je le faire réinitialiser la minuterie lorsqu'un bouton est enfoncé après que la minuterie est déjà épuisée?
crmepham

104

J'ai écrit ce script il y a quelque temps:

Usage:

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
J'adorerais utiliser ceci au lieu des autres. Quand j'étais coincé pour redémarrer le numéro de départ, je vois que cela fonctionne bien ..
Oki Erie Rinaldi

Si je dois arrêter le chronomètre par hasard, comment puis-je le faire?
SIJ

@SIJ myCounter.stop();
R3tep

54

Jusqu'à présent, les réponses semblent reposer sur le code exécuté instantanément. Si vous réglez une minuterie sur 1000 ms, elle sera en fait d'environ 1008 à la place.

Voici comment procéder:

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
}

Pour l'utiliser, appelez:

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 on, comme vous l'avez dit, c'est le seul et unique moyen de bien faire les choses!
mcella

3
Je lui ai donné un coup de pouce, avec une mise en garde - à des fins d'affichage, vous souhaitez probablement afficher le plafond (Math.ceil ()) au lieu du sol. C'est vraiment désorientant lorsque l'horloge atteint 0 une seconde avant que l'alerte ne se déclenche. (Ensuite, bien sûr, il doit y avoir un appel supplémentaire à update () avant la fin ())
Paul Williams

21

En voici un autre si quelqu'un en a besoin pendant quelques minutes et secondes:

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

Vous ne devriez pas passer une chaîne au premier paramètre de setTimeout, setTimeout(Decrement, 1000)c'est préférable. stackoverflow.com/questions/6232574/…
Scottux

Merci pour la suggestion, j'ai mis à jour le script.
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
Ce script utilise de très mauvaises pratiques des années 90. Et aussi 1,5 heure n'est pas 2 heures. C'est 1 heure 30 min. Vous devriez utiliser Math.floor, pasMath.round
corbacho

3

Je viens de modifier la réponse de @ ClickUpvote :

Vous pouvez utiliser IIFE (Immediately Invoked Function Expression) et la récursivité pour le rendre un peu plus facile:

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


2

Si vous étendez la réponse acceptée, la mise en veille de votre machine, etc. peut retarder le fonctionnement de la minuterie. Vous pouvez obtenir un temps réel, au prix d'un peu de traitement. Cela donnera un vrai temps restant.

<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

Vous pouvez faire comme suit avec pur JS. Il vous suffit de fournir à la fonction le nombre de secondes et elle fera le reste.

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

Sur la base de la solution présentée par @Layton Everson, j'ai développé un compteur comprenant les heures, les minutes et les secondes:

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

Ma solution fonctionne avec les formats de date et d'heure MySQL et fournit une fonction de rappel. sur complition. Avertissement: fonctionne uniquement avec les minutes et les secondes, car c'est ce dont j'avais besoin.

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

Pour des raisons de performances, nous pouvons désormais utiliser en toute sécurité requestAnimationFrame pour une boucle rapide, au lieu de setInterval / setTimeout.

Lors de l'utilisation de setInterval / setTimeout, si une tâche de boucle prend plus de temps que l'intervalle, le navigateur étendra simplement la boucle d'intervalle, pour continuer le rendu complet. Cela crée des problèmes. Après quelques minutes de surcharge setInterval / setTimeout, cela peut geler l'onglet, le navigateur ou tout l'ordinateur.

Les appareils Internet ont un large éventail de performances, il est donc tout à fait impossible de coder en dur un intervalle de temps fixe en millisecondes!

À l'aide de l' objet Date , pour comparer la date de début et l'époque actuelle. Ceci est beaucoup plus rapide que tout le reste, le navigateur se chargera de tout, à un rythme régulier 60fps (1000/60 = 16.66ms par image ) - un quart d'un clin d'oeil - et si la tâche dans la boucle exige plus que , le navigateur supprimera quelques repeints.

Cela laisse une marge avant que nos yeux ne le remarquent ( Humain = 24FPS => 1000/24 ​​= 41,66ms par image = animation fluide!)

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>

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.