Compte à rebours en JavaScript

Base

Nous allons commencer par créer dans un fichier .html une div avec un id compte_a_rebours, suivi de notre code JavaScript. On crée ensuite une variable pour sélectionner cette div.

1 <div id="compte_a_rebours"></div>
2 <script type="text/javascript">
3     var compte_a_rebours = document.getElementById("compte_a_rebours");
4 </script>

Attention à bien mettre le code JavaScript après la div. En effet, vu que le JavaScript s'exécute en même temps que le chargement de la page, l'id compte_a_rebours n'existera encore pas.

Calculs du nombre de jours, heures, minutes et secondes

On crée une variable pour la date actuelle.

1 var date_actuelle = new Date();

Puis celle pour l'évènement.

Syntaxe : Mois Jour Heures:Minutes:Secondes Année. Attention à bien mettre le nom du mois en anglais, et ne garder que les 3 premières lettres.

1 var date_evenement = new Date("Jan 1 00:00:00 2018");

Ici on choisit le 1 janvier 2018.

Voici comment nous allons procéder :

  • On calcule la différence entre les deux dates (date_evenement - date_actuelle).
  • Si la différence est strictement positive, le compte à rebours n'est pas terminé.
  • Si la différence est nulle, alors le compte à rebours vient de se terminer à l'instant.
  • Sinon (la différence est strictement négative), le compte à rebours est terminé. Dans ce cas-là, on calculera depuis combien de temps il est terminé.

Les variables des deux dates sont en millisecondes. On fait donc une soustraction des deux dates, puis on les divise par 1000 afin d'avoir une différence en secondes.

1 var total_secondes = (date_evenement - date_actuelle) / 1000;

Pour différencier si le compte à rebours est terminé ou non, on va ajouter un préfixe, qui, en fonction de la différence, vaudra "Compte à rebours terminé dans " ou "Compte à rebours terminé il y a ". Dans le cas où la différence est négative, on modifiera la valeur de total_secondes pour lui mettre sa valeur absolue, afin que l'on puisse faire nos calculs plus tard correctement.

 1 var prefixe = "Compte à rebours terminé dans ";
 2 if (total_secondes < 0)
 3 {
 4     prefixe = "Compte à rebours terminé il y a "; // On modifie le préfixe si la différence est négatif
 5     total_secondes = Math.abs(total_secondes); // On ne garde que la valeur absolue
 6 }
 7 
 8 if (total_secondes > 0)
 9 {
10     // A faire, tous nos calculs
11 }
12 else // Si total_secondes == 0 (puisque l'on a prit sa valeur absolue)
13 {
14     compte_a_rebours.innerHTML = 'Compte à rebours terminé.';
15 }

Nous allons maintenant calculer le nombre de jours, d'heures, de minutes et de secondes restants.

Le nombre étant en secondes, 1 jour = 60 x 60 x 24 secondes.

La différence divisée par ce nombre nous donne le nombre de jours restants.

On récupère alors le plus grand entier inférieur ou égal à la valeur retournée (on tronque à l'unité), afin de ne pas avoir 10.345 jours restants, mais 10. On utilise pour cela la fonction Math.floor().

1 var jours = Math.floor(total_secondes / (60 * 60 * 24));

Passons aux heures restantes.

Sur les 10.345 jours restants (par exemple), on n'a gardé seulement 10. Il reste donc 0.345 jour, que nous allons devoir convertir en heures.

On soustrait donc aux secondes totales le nombre de jours (en secondes). Ça permet de récupérer les 0.345 jour (mais en secondes).

Vu que 1 heure = 60 x 60 secondes, la différence divisée par ce nombre nous permet d'obtenir le nombre d'heures restantes.

Pareil que pour les jours, on récupère le plus grand entier inférieur ou égal à la valeur retournée.

1 var heures = Math.floor((total_secondes - (jours * 60 * 60 * 24)) / (60 * 60));

Mêmes techniques pour les minutes et les secondes :

1 minutes = Math.floor((total_secondes - ((jours * 60 * 60 * 24 + heures * 60 * 60))) / 60);
2 secondes = Math.floor(total_secondes - ((jours * 60 * 60 * 24 + heures * 60 * 60 + minutes * 60)));

Affichage

Il nous reste plus qu'à afficher le résultat.

1 compte_a_rebours.innerHTML = prefixe + jours + ' jours ' + heures + ' heures ' + minutes + ' minutes et ' + secondes + ' secondes.';

Améliorations

Maintenant, nous allons améliorer tout ça pour avoir un meilleur résultat.

  • Si c'est 0 jour (ou 0 heure, ou 0 minute, ou 0 seconde), alors on ne les affiche pas. Exemple, s'il reste 0 jours, 3 heures, 0 minutes et 0 secondes, on n'affiche que 3 heures
  • De plus, s'il reste 1 jour (ou heure, ou mi...), alors on enlève le s
  • Modifier le script pour qu'il s'actualise toutes les secondes, cela évitera de recharger la page pour voir le temps restant
  • Afficher un message d'erreur pour ceux qui n'ont pas leur JavaScript d'activé

Les mots et "s" en trop

Pour résoudre les deux premiers points, on peut remplacer ceci :

1 compte_a_rebours.innerHTML = prefixe + jours + ' jours ' + heures + ' heures ' + minutes + ' minutes et ' + secondes + ' secondes.';

Par :

 1 var et = "et";
 2 var mot_jour = "jours,";
 3 var mot_heure = "heures,";
 4 var mot_minute = "minutes,";
 5 var mot_seconde = "secondes";
 6 
 7 if (jours == 0)
 8 {
 9     jours = '';
10     mot_jour = '';
11 }
12 else if (jours == 1)
13 {
14     mot_jour = "jour,";
15 }
16 
17 if (heures == 0)
18 {
19     heures = '';
20     mot_heure = '';
21 }
22 else if (heures == 1)
23 {
24     mot_heure = "heure,";
25 }
26 
27 if (minutes == 0)
28 {
29     minutes = '';
30     mot_minute = '';
31 }
32 else if (minutes == 1)
33 {
34     mot_minute = "minute,";
35 }
36 
37 if (secondes == 0)
38 {
39     secondes = '';
40     mot_seconde = '';
41     et = '';
42 }
43 else if (secondes == 1)
44 {
45     mot_seconde = "seconde";
46 }
47 
48 if (minutes == 0 && heures == 0 && jours == 0)
49 {
50     et = "";
51 }
52 
53 compte_a_rebours.innerHTML = prefixe + jours + ' ' + mot_jour + ' ' + heures + ' ' + mot_heure + ' ' + minutes + ' ' + mot_minute + ' ' + et + ' ' + secondes + ' ' + mot_seconde;

Je pense qu'une simple lecture devrait vous permettre de comprendre ce code.

Ré-actualisation automatique

Maintenant, passons à la ré-actualisation automatique du compte à rebours.

Pour cela, nous allons devoir englober notre code dans une fonction, que nous exécuterons toutes les secondes, grâce à la fonction setTimeout :

1 actualisation = setTimeout("compte_a_rebours();", 1000);

Cette ligne aura pour action de lancer la fonction compte_a_rebours() dans 1000 millisecondes (donc dans une seconde).

On l'ajoutant à la fin de notre fonction, celle-ci sera donc exécutée chaque seconde.

Pour l'appeler la première fois, il nous suffit de la faire exécuter après l'avoir fait déclarer.

On obtient :

1 function compte_a_rebours()
2 {
3     // Code que l'on a écrit auparavant
4     var actualisation = setTimeout("compte_a_rebours();", 1000);
5 }
6 compte_a_rebours();

Pour les utilisateurs n'ayant pas le JavaScript d'activé

Une dernière petite amélioration consiste à afficher un message d'erreur si le JavaScript n'est pas activé.

On remplace donc ceci :

1 <div id="compte_a_rebours"></div>

Par :

1 <div id="compte_a_rebours"><noscript>Merci d'activer votre JavaScript.</noscript></div>

La balise noscript n'affiche son contenu seulement si le JavaScript est désactivé.

Vous pouvez aussi, au lieu d'afficher ce message d'erreur pas toujours très agréable, afficher un texte manuellement pour dire quand ce termine le compte à rebours :

1 <div id="compte_a_rebours"><noscript>Fin de l'évènement le 1er janvier 2018.</noscript></div>

Codes complets

Et voilà ! Tout devrait fonctionner.

 1 <div id="compte_a_rebours"><noscript>Fin de l'évènement le 1er janvier 2018.</noscript></div>
 2 <script type="text/javascript">
 3 function compte_a_rebours()
 4 {
 5     var compte_a_rebours = document.getElementById("compte_a_rebours");
 6 
 7     var date_actuelle = new Date();
 8     var date_evenement = new Date("Jan 1 00:00:00 2017");
 9     var total_secondes = (date_evenement - date_actuelle) / 1000;
10 
11     var prefixe = "Compte à rebours terminé dans ";
12     if (total_secondes < 0)
13     {
14         prefixe = "Compte à rebours terminé il y a "; // On modifie le préfixe si la différence est négatif
15         total_secondes = Math.abs(total_secondes); // On ne garde que la valeur absolue
16     }
17 
18     if (total_secondes > 0)
19     {
20         var jours = Math.floor(total_secondes / (60 * 60 * 24));
21         var heures = Math.floor((total_secondes - (jours * 60 * 60 * 24)) / (60 * 60));
22         minutes = Math.floor((total_secondes - ((jours * 60 * 60 * 24 + heures * 60 * 60))) / 60);
23         secondes = Math.floor(total_secondes - ((jours * 60 * 60 * 24 + heures * 60 * 60 + minutes * 60)));
24 
25         var et = "et";
26         var mot_jour = "jours,";
27         var mot_heure = "heures,";
28         var mot_minute = "minutes,";
29         var mot_seconde = "secondes";
30 
31         if (jours == 0)
32         {
33             jours = '';
34             mot_jour = '';
35         }
36         else if (jours == 1)
37         {
38             mot_jour = "jour,";
39         }
40 
41         if (heures == 0)
42         {
43             heures = '';
44             mot_heure = '';
45         }
46         else if (heures == 1)
47         {
48             mot_heure = "heure,";
49         }
50 
51         if (minutes == 0)
52         {
53             minutes = '';
54             mot_minute = '';
55         }
56         else if (minutes == 1)
57         {
58             mot_minute = "minute,";
59         }
60 
61         if (secondes == 0)
62         {
63             secondes = '';
64             mot_seconde = '';
65             et = '';
66         }
67         else if (secondes == 1)
68         {
69             mot_seconde = "seconde";
70         }
71 
72         if (minutes == 0 && heures == 0 && jours == 0)
73         {
74             et = "";
75         }
76 
77         compte_a_rebours.innerHTML = prefixe + jours + ' ' + mot_jour + ' ' + heures + ' ' + mot_heure + ' ' + minutes + ' ' + mot_minute + ' ' + et + ' ' + secondes + ' ' + mot_seconde;
78     }
79     else
80     {
81         compte_a_rebours.innerHTML = 'Compte à rebours terminé.';
82     }
83 
84     var actualisation = setTimeout("compte_a_rebours();", 1000);
85 }
86 compte_a_rebours();
87 </script>

JavaScript

Article publié le 16 Octobre 2010.

Commentaires