11526 sujets

JavaScript, DOM et API Web HTML5

Bonjour, j'ai pour projet de faire un minuteur. Le plus gros est déjà fait, mais des finissions me posent problèmes.
Tout d'abord, j'aimerais que les unités de temps s'affichent toujours avec deux chiffres. Il faudrait donc placer un 0 devant les valeurs inférieur à 10. Cependant, je ne pas comment le faire simplement.
De plus, vous allez voir dans le code si dessous, j'ai un des lignes qui se répètent. Il y a t'il un moyen d'y remédier ?
Merci d'avance.


function timerDisplay(h, m, s) {
    let time = h * 360 + m * 6 + s
    document.querySelector('circle').style.animation = `circle ${time}s both linear`

    document.querySelector('h3').innerHTML = `${h}:${m}:${s}`

    if(h == 0 && m == 0 && s == 0) {
        document.querySelector('h3').style.display = 'none'
        document.getElementById('clock_end').style.display = 'unset'
        document.querySelector('audio').play()
    }
    if(m == 0 && s == 0) {
        if(h > 0) {
            m = 59
            h--
        }
    }
    if(s == 0) {
        s = 59
        m--
    } 
    else {s--}

    setInterval(() => {
        document.querySelector('h3').innerHTML = `${h}:${m}:${s}`

        if(h == 0 && m == 0 && s == 0) {
            document.querySelector('h3').style.display = 'none'
            document.getElementById('clock_end').style.display = 'unset'
            document.querySelector('audio').play()
        }
        if(m == 0 && s == 0) {
            if(h > 0) {
                m = 59
                h--
            }
        }
        if(s == 0) {
            s = 59
            m--
        } 
        else {s--}
    }, 1000)
}
Modérateur
Coucou !


pour le 0 tu peux bricoler un truc du genre :
if (m< 10) { 
   min= '0' + m;
}
document.querySelector('h3').innerHTML = `${h}:${min}:${s}`

Juste avant l'affichage

Pour factoriser ton bout de code tu peux en faire une fonction. Et pour moins t'embêter à tout passer en argument et retourner, tu peux mettre les variables à l'extérieur :
let h=10;
let m=0;
let s=0;

timerDisplay();

function timerDisplay() {
  let time = h * 360 + m * 6 + s;
  neverGiveYouUp();
  setInterval(() => {
    neverGiveYouUp();
  }, 1000)
}

function neverGiveYouUp() {
  document.querySelector('h3').innerHTML = `${h}:${m}:${s}`

  if(h == 0 && m == 0 && s == 0) {
    document.querySelector('h3').style.display = 'none'
  }
  if(m == 0 && s == 0) {
    if(h > 0) {
      m = 59
      h--
    }
  }
  if(s == 0) {
    s = 59
    m--
  } 
  else {s--}
}

le test : https://jsfiddle.net/Lmv83hp7/


Mais sinon pourquoi tu répètes ce gros bloc de code ? Pour éviter d'attendre 1 seconde au démarrage ? Et si tu affichait le temps dès que tu lance la fonction, et que tu lance le setTimout avec l'affichage à la fin ? Je reprend ton code de départ :

function timerDisplay(h, m, s) {
  let time = h * 360 + m * 6 + s

  document.querySelector('h3').innerHTML = `${h}:${m}:${s}`

  setInterval(() => {

    if (h == 0 && m == 0 && s == 0) {
            document.querySelector('h3').style.display = 'none'
            document.getElementById('clock_end').style.display = 'unset'
            document.querySelector('audio').play()
    }
    if (m == 0 && s == 0) {
      if (h > 0) {
        m = 59
        h--
      }
    }
    if (s == 0) {
      s = 59
      m--
    } else {
      s--
    }
    document.querySelector('h3').innerHTML = `${h}:${m}:${s}`
  }, 1000)
}


ca évite la répétition du bout de code et tu peux faire une fonction pour le display si tu veux y mettre plus de choses.

PS : tu peux mettre ton H3 dans une variable au début du code ca évitera les querySelector à tour de bras :

let monH3 = document.querySelector('h3');
// ...
// ...
// ...
  monH3.innerHTML = `${h}:${m}:${s}`



PSencore : j'allait te dire qu'il manquait tout les point-virgules à la fin de tes lignes mais ca marche sans dans le fiddle... j'ai dormi combien de temps ? On est dans le futur ? Que se passe-t-il ?! Smiley biggol
Merci pour ton retour. J'ai réussi à bricolé quelque chose de pas trop complexe pour mon premier problème.
Cependant, je n'arrive toujours pas à retirer ma répétition de code. J'avais déjà essayé l'utilisation de fonction, mais pour je ne sais quelle raison, l'appelle de fonction dans le setInterval ne fonctionne pas.
Pour répondre à ta dernière question, je répète le bout de code pur car sinon l'affichage commence après les 1s imposé par le setInterval. De ton coté ton programme n'a pas ce problème, mais je ne comprends pas pourquoi…
Modérateur
Heu, bah a part répéter ce que j'ai écrit je vois pas... j'ai déjà répondu au pourquoi du comment et je t'ai donné un exemple avec une fonction et j'ai aussi proposé une amélioration sur ton code pour se passer de la répétition et des 1s de décalage Smiley sweatdrop
Je pense avoir bien compris tes messages précédent, mais dans ma situation les solutions proposés créent un décalage ou affecte l'affichage de mon minuteur. Je ne comprends pas pourquoi. Mais mon code, bien que répétitif fonctionne et je vais me contenter de ça. Merci encore de ton aide.
Salut,

Je me suis dis qu'on devait pouvoir généraliser "facilement" en utilisant des dates pour ne pas avoir à gérer le passage des heures vers les minutes puis vers les secondes Smiley lol

Bon bah c'est pas du tout si facile que ça (pour le coup je dirais que c'est même plutôt mal foutu à mon goût Smiley bawling )
J'étais persuadé qu'on pouvait facilement affiché un timestamp au format voulu en précisant hh:mm:ss mais je dois confondre parce que ça n'a pas l'air natif au javascript ..

Enfin bon du coup en cherchant j'ai fini par tomber sur un chouette exemple ici : https://codepen.io/SitePoint/pen/NWxKgxN (même au final cela ne simplifiera pas le traitement vu qu'il faut récupérer les heures/minutes /secondes un par un ..)
Modérateur
Bonjour,

Mathieuu a écrit :
J'étais persuadé qu'on pouvait facilement affiché un timestamp au format voulu en précisant hh:mm:ss ...

Ça me semble en effet pas mal de se baser sur un timestamp.

On peut afficher un timestamp au format hh:mm:ss sans calcul (mais avec quand même une ligne de code pas tout à fait triviale). Par exemple :
let d=new Date(12345000);
let t=(d.getUTCHours()+"").padStart(2,"0")+":"+(d.getUTCMinutes()+"").padStart(2,"0")+":"+(d.getUTCSeconds()+"").padStart(2,"0");
Ce qui donnera ici "03:25:45" correspondant à 12345 secondes écoulées.

Comme ici, le minuteur a 3 champs distincts, on va dire qu'on a 3 variables h, m et s pour stocker ça au lieu de la seule variable t. Il suffit alors de faire :
let d=new Date(12345000);
let h=(d.getUTCHours()+"").padStart(2,"0");
let m=(d.getUTCMinutes()+"").padStart(2,"0");
let s=(d.getUTCSeconds()+"").padStart(2,"0");
Pas tout à fait simple, mais pas très compliqué quand même me semble-t-il !

Amicalement,
\ô/
on peut également utiliser la méthode toLocaleString pour formater la réponse, par exemple :
const MS = 1000;
let time = 12345000;

for (let count = 0; count < 10; count += 1) {
  const date = new Date(time);
    const timeOutput = date.toLocaleString("fr-FR", {timeZone: "UTC"})
    //    .replace(/\u200e/g, "")   // si besoin IE
    .split(" ")
    .pop();
  console.log(timeOutput);
  time -= MS;
}


EDIT : ajout du timeZone pour coller au besoin
Modifié par Dave-Hiock (25 Feb 2022 - 10:20)
parsimonhi a écrit :

let d=new Date(12345000);
let h=(d.getUTCHours()+"").padStart(2,"0");
let m=(d.getUTCMinutes()+"").padStart(2,"0");
let s=(d.getUTCSeconds()+"").padStart(2,"0");
Pas tout à fait simple, mais pas très compliqué quand même me semble-t-il !


J'aime bien vos solutions, j'avais sans doute un peu trop complexifié pour mes tests je crois Smiley sweatdrop

Et sinon j'ai retrouvé, c'est en php que c'est faisable en un seul coup :
$today = date("H:i:s"); ( https://www.php.net/manual/en/function.date.php )