11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous,
Je viens vers vous car j'ai un script de chronomètre qui ne fonctionne pas. J'ai étudié le script et je ne vois rien de particulier. C'est peut-être trois fois rien comme d'habitude avec JavaScript.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Document sans nom</title>
    <script>
var h1 = document.getElementsByTagName('h1')[0];
var start = document.getElementById('strt');
var stop = document.getElementById('stp');
var reset = document.getElementById('rst');
var sec = 0;
var min = 0;
var hrs = 0;
var t;

function tick(){
    sec++;
    if (sec >= 60) {
        sec = 0;
        min++;
        if (min >= 60) {
            min = 0;
            hrs++;
        }
    }
}
function add() {
    tick();
    h1.textContent = (hrs > 9 ? hrs : "0" + hrs) 
        	 + ":" + (min > 9 ? min : "0" + min)
       		 + ":" + (sec > 9 ? sec : "0" + sec);
    timer();
}
function timer() {
    t = setTimeout(add, 1000);
}

timer();
start.onclick = timer;
stop.onclick = function() {
    clearTimeout(t);
}
reset.onclick = function() {
    h1.textContent = "00:00:00";
    seconds = 0; minutes = 0; hours = 0;
}

        </script>
</head>

<body>
<h1><time>00:00:00</time></h1>
<button id="strt">start</button>
<button id="stp">stop</button>
<button id="rst">reset</button>

</body>
</html>
Merci pour votre réponse.
Votre lien pointe vers le même code que j'utilise.
Le chronomètre de démarre pas et quand je clique sur 'start', le chronomètre ne se déclenche pas!! Les trois boutons sont inactif.
Modifié par luxojr (27 Jan 2022 - 16:47)
Modérateur
luxojr a écrit :
Votre lien pointe vers le même code que j'utilise.

Oui c'est moi qui ai copier collé le code pour voir le comportement et tenter de savoir par moi même ce qui ne marchait pas.

luxojr a écrit :
Le chronomètre de démarre pas et quand je clique sur 'start', le chronomètre ne se déclenche pas!! Les trois boutons sont inactif.

Si vous allez sur ce lien justement, le chronomètre marche bien... Même un peu trop bien puisqu'il démarre automatiquement avant l'appui sur start, ce qui crée un soucis d'ailleurs car si on clique plusieurs fois sur "start" ca rajoute autant de décompte par seconde que de clique. Bref il faut bloquer le lancement automatique du chrono et surtout bloquer le lancement du chrono si il est déjà en action.

Sinon le stop marche bien tout comme le reset.

Rien ne marche quand vous regardez le lien que j'ai posté ? Vous utilisez quel navigateur ?
\ô/
attention à chaque appui sur le bouton start il faut « clearer » le timer sinon il y en aura plusieurs en cours
start.onclick = () => {
    clearTimeout(t);
    timer();
}

idem pour le reset.
Modérateur
luxojr a écrit :
J'ai copié le code issu de votre lien et il ne fonctionne toujours pas. ?!? Smiley decu Smiley decu Smiley decu

Je ne demande pas ça. Le code qui est dans ce lien c'est votre code pas besoin de le recopier vous l'avez déjà. Je vous demande si, en allant sur le lien, vous voyez le chronomètre fonctionner dans l'encart en bas a droite ?
Modérateur
Dave-Hiock a écrit :
\ô/
attention à chaque appui sur le bouton start il faut « clearer » le timer sinon il y en aura plusieurs en cours
idem pour le reset.


Il faut surtout rajouter un bool pour savoir si le chrono fonctionne ou pas parceque si on clique plusieur fois sur start ca en lance plusieurs sur la meme variable Smiley lol
Le chronomètre lié à votre lien fonctionne dans mon navigateur. Vous pouvez préciser l'implémentation du booléen.
_laurent a écrit :
parceque si on clique plusieur fois sur start ca en lance plusieurs sur la meme variable Smiley lol

non car on kill l'appel en cours, par contre effectivement comme on utilise les mêmes variables donc il y a continuité dans le comptage.
Modérateur
Dave-Hiock a écrit :

non car on kill l'appel en cours, par contre effectivement comme on utilise les mêmes variables donc il y a continuité dans le comptage.

Bah quand je clique 3 fois sur start par exemple on voit le compteur prendre 3 seconde toutes les secondes.. ou est-ce que tu vois qu'on kill l'appel en cours ?
https://jsfiddle.net/undless/vu2by10t/ hop 5 coucou toutes les 2 secondes. C'est en gros ce qu'on fait quand on clique plusieurs fois sur start.

luxojr a écrit :
Le chronomètre lié à votre lien fonctionne dans mon navigateur.

C'est que le code fonctionne alors. Le soucis vient d'ailleurs : la façon dont vous incluez le code par exemple. Est-ce que dans le cas ou le code ne marche pas la console donne une erreur ?

luxojr a écrit :
Vous pouvez préciser l'implémentation du booléen.

Mettre un booléen à false et ne le passer à true qu'a l'appuie sur start. Sur un nouvel appui sur start si le booléen est déjà a true il ne faut rien faire de plus. Pour le stop ca serait l'inverse.

timer();

c'est lui qui lance le timer à l'ouverture btw.
Modifié par _laurent (28 Jan 2022 - 16:02)
_laurent a écrit :
Bah quand je clique 3 fois sur start par exemple on voit le compteur prendre 3 seconde toutes les secondes.. ou est-ce que tu vois qu'on kill l'appel en cours ?

je n'ai pas dit que l'on killer l'appel en cours dans le code présenté, j'ai dit qu'il fallait penser à le killer !

On peut faire ainsi
// attendre appui sur start
//timer();
start.onclick = () => {
    // on peut ajouter
    start.disabled = true;
    // kill appel en cours
    clearTimeout(t);
    // lance l'appel avec les valeurs en cours
    timer();
}
stop.onclick = function() {
    // kill appel en cours
    clearTimeout(t);
    // réactive le bouton start
    start.disabled = false;
}
reset.onclick = function() {
    // kill appel en cours
    clearTimeout(t);
    // réactive le bouton start
    start.disabled = false;
    // reinit des valeurs
    h1.textContent = "00:00:00";
    sec = 0;
    min = 0;
    hrs = 0;
}

on pourrait également faire un stop.click() directement dans la fonction reset
reset.onclick = function() {
    // appel au bouton stop
    stop.click();
    // reinit des valeurs
    h1.textContent = "00:00:00";
    sec = 0;
    min = 0;
    hrs = 0;
}

PS : les variables à réinitialiser n'étaient pas les bonnes.
Je reviens après relecture entière de la discussion, j'étais trop focalisé sur le jsfiddle !
luxojr a écrit :
J'ai étudié le script et je ne vois rien de particulier.

il y a quand même quelque chose d'important, le fait d'initialiser des variables, comme h1, start, stop et reset avec document.getElementById() alors que les éléments ne sont pas encore dans la page, le DOM, puisque le script intervient en début de page et la mise en place des éléments après, fait planter l'ensemble.
Modérateur
Dave-Hiock a écrit :

je n'ai pas dit que l'on killer l'appel en cours dans le code présenté, j'ai dit qu'il fallait penser à le killer !

ok ok j'avais mal compris Smiley smile
par contre en faisant ca ca décale un peu le temps. Ca stop le timer la ou il est et ca en relance un nouveau donc selon le moment ou on clique on peut avoir une seconde de deux seconde...

+1 pour le code qui s'exécute avant le DOM
Bonjour à tous et merci pour vos réponse...
J'ai implémenté le code fourni par Dave-Hiock. Cela ne change rien, le chronomètre refuse de démarrer. Smiley decu
Les 3 boutons ne réagissent pas au clic de la souris.
Modérateur
Oui normal ce qui était important est dans son second commentaire :

Dave-Hiock a écrit :
il y a quand même quelque chose d'important, le fait d'initialiser des variables, comme h1, start, stop et reset avec document.getElementById() alors que les éléments ne sont pas encore dans la page, le DOM, puisque le script intervient en début de page et la mise en place des éléments après, fait planter l'ensemble.


Il faut exécuter ton code une fois que le DOM est pret. Donc soit le mettre dans un document.addEventListener('DOMContentLoaded' soit le mettre dans le body à la fin de ton HTML juste avant de fermer le body.