Pure JS Full Countdown Timer - Troublesome Countdown

Asked

Viewed 6,259 times

2

People, I am creating a countdown timer accompanied by the buttons (start, pause, reset, restart and save time) and the initial time is set in an input as well.

I searched several times in various posts on pt.stackoverflow and other internet forums, I found at most regressive chronometers, but not with the same functionalities and although I tried to adapt I could not. In our forum we only find similar questions, but the language is not the same and when it is (pure js), the purpose is very different.

My code is with counting problem, I have noticed problems when it is more than 10 minutes or less than 1. I would like a resolution in Pure JS! Observe the code:

Javascript

    function transporta(mensagem){
            var docsetmin = document.getElementById('setminutos');
            var docsetsec = document.getElementById('setsegundos');
            var docrestamin = document.getElementById('restamin');
            var docrestasec = document.getElementById('restasec');

            if(docsetsec.value <= 59){
                docrestamin.value = docsetmin.value;
                docrestasec.value = docsetsec.value;
                setTimeout(cronometro, 1000, 'start');
            }
            else{
                alert('Há problemas com o tempo configurado!');
            }

        }

        function cronometro(option, message){

            var docsetmin = document.getElementById('setminutos');
            var docsetsec = document.getElementById('setsegundos');
            var docrestamin = document.getElementById('restamin');
            var docrestasec = document.getElementById('restasec');
            var docsetminval = docsetmin.value;
            var docsetsecval = docsetsec.value;
            var docrestaminval = docrestamin.value;
            var docrestasecval = docrestasec.value;

            if(option == 'start'){
                start(message);
            }
            if(option == 'pause'){
                docrestamin.placeholder = docrestamin.value;
                docrestasec.placeholder = docrestasec.value;
                alert('Cronômetro Pausado');
                docrestamin.value = '--';
                docrestasec.value = '--';
                document.getElementById('paused').innerHTML = 'Pausado em: ' + docrestamin.placeholder + ':' + docrestasec.placeholder + '.';
            }
            if(option == 'reset'){
                docsetmin.value = '00';
                docsetsec.value = '00';
                docrestamin.value = '00';
                docrestasec.value = '00';
                docrestamin.placeholder = '';
                docrestasec.placeholder = '';
                docsetmin.placeholder = '';
                docsetsec.placeholder = '';
            }
            if(option == 'resume'){
                document.getElementById('paused').innerHTML = '';
                docrestamin.value = docrestamin.placeholder;
                docrestasec.value = docrestasec.placeholder;
                cronometro('start', message);
            }
            if(option == 'save'){
                alert(docsetmin.value + ':' + docsetsec.value);
            }
        }

        function start(alerta){


            var docsetmin = document.getElementById('setminutos');
            var docsetsec = document.getElementById('setsegundos');
            var docrestamin = document.getElementById('restamin');
            var docrestasec = document.getElementById('restasec');

            /* Se for mais que 10 minutos */
            if(docrestamin.value > 10){

                /* Se for mais que 10 segundos */
                if((docrestasec.value <= 59) && (docrestasec.value > 10)){
                    docrestasec.value = docrestasec.value - 1;
                    setTimeout(start, 1000);        
                }

                /* Se for menor ou igual a 10 segundos e mais que 0 segundos */
                if((docrestasec.value <= 10) && (docrestasec.value > 0)){
                    var ts = docrestasec.value - 1;
                    docrestasec.value = '0' + ts;
                    setTimeout(start, 1000, 'start');
                }

                /* Se for menor ou igual a 0 segundos */
                if(docrestasec.value <= 0){
                    docrestasec.value = '59';
                    docrestamin.value = docrestamin.value - 1;
                    setTimeout(start, 1000, 'start');   
                }
            }

            /* Se for menor ou igual a 10 minutos e mais que 0 minutos */
            if((docrestamin.value <= 10) && (docrestamin.value > 0)){

                /* Se for mais que 10 segundos */
                if((docrestasec.value > 10) && (docrestasec.value <= 59)){
                    docrestasec.value = docrestasec.value - 1;
                    setTimeout(start, 1000, 'start');    
                }

                /* Se for menor ou igual a 10 segundos e mais que 0 segundos */
                if(docrestasec.value <= 10 && docrestasec.value > 0){
                    var ts = docrestasec.value - 1;
                    docrestasec.value = '0' + ts;
                    setTimeout(start, 1000, 'start');
                }

                /* Se for menor ou igual a 0 segundos */
                if(docrestasec.value <= 0){
                    var tm = docrestamin.value - 1;
                    docrestamin.value = '0' + tm;
                    docrestasec.value = 59;
                    setTimeout(start, 1000, 'start');
                }
            }

            /* Se for menor ou igual a 0 minutos */
            if(docrestamin.value <= 0){

                /* Se for mais que 10 segundos */
                if((docrestasec.value <= 59) && (docrestasec.value > 10)){
                    docrestasec.value = docrestasec.value - 1;
                    setTimeout(start, 1000, 'start');
                }

                /* Se for menor ou igual a 10 segundos e mais que 0 segundos */
                if((docrestasec.value <= 10) && (docrestasec.value > 0)){
                    var ts = docrestasec.value - 1;
                    docrestasec.value = '0' + ts;
                    setTimeout(start, 1000, 'start');    
                }

                /* Se for menor ou igual a 0 segundos */
                if(docrestasec.value <= 0){
                    if((docrestamin.value = '00') && (docrestasec.value = '00')){
                        alert('O tempo acabou!');
                    }
                }
            }
        }

        function Onlynumbers(){
            var tecla = event.keyCode;
            if((tecla >= "48") && (tecla <= "57") && (tecla = "186")){
                return true;
            }
            else{
                return false;
            }
        }

CSS3

    body{padding: 20%;}
        header{text-align: center;}
        section{align-items: center; justify-content: center; display: flex; vertical-align: middle;}
        .btn{color: black; border: none; background-color: white; margin-left: 0.5%; margin-right: 0.5%; text-align: center;}
        .border{border: 1px solid black;}
        .border{transition: background-color 0.4s ease-in 0.2s; transition: color 0.01s ease-in;}
        .border:hover{background-color: #1397D4; color: white;}

HTML

    <!-- Cronômetro Regressivo -->
    <header>
        <p><h1>Cronômetro Regressivo</h1></p>
    </header>
    <br>
    <section>
        <input placeholder="m" class="btn" id="setminutos" type="text" name="minutos" size="2" maxlength="2" onkeypress="return Onlynumbers()">
        :
        <input placeholder="s" class="btn" id="setsegundos" maxlength="2" type="text" name="segundos" size="2" onkeypress="return Onlynumbers()">
            <button id="comece" class="btn border" type="button" onclick="transporta()">Iniciar</button>               
            <button class="btn border" onclick="cronometro('pause');">Pausar</button>
            <button class="btn border" onclick="cronometro('reset')">Resetar</button>
            <button class="btn border" onclick="cronometro('resume')">Reiniciar</button>
            <button class="btn border" onclick="cronometro('save')">Salvar Tempo</button>



                <input class="btn dnone" id="restamin" type="text" name="minutosresta" size="2" maxlength="2" onkeypress="return Onlynumbers()">
                <div class="dnone">:</div>
                <input class="btn dnone" id="restasec" maxlength="2" type="text" name="segundosresta" size="2" onkeypress="return Onlynumbers()">
                <div id="paused" class="dnone"></div>
    </section>

1 answer

5


follows html code, css and javascript. copy the code into three separate files and make the modification to your liking:

var configMinuto;
var configSegundo;
var mostrarValor;
var evento = null;
var contador = null;
var minuto = 0;
var segundo = 0;

function IniciarCronometro(valor){
	this.evento = valor;
	this.configMinuto = document.getElementById('min').value;
	this.configSegundo = document.getElementById('seg').value;
	this.mostrarValor = document.getElementById('mostrarValor');
	
	
	if (evento=="start"){
		if(!document.getElementById('min').readOnly){
			if(!this.validarNumero(this.configMinuto)){
				alert("Campo minuto não é um número!");
				return;
			}
			if(!this.validarNumero(this.configSegundo) || document.getElementById('seg').value > 59){
				alert("Campo segundo não é um número válido (0 a 59)!");
				return;
			}
			
			document.getElementById('min').readOnly = true;
			document.getElementById('seg').readOnly = true;
			document.getElementById('btnIniciar').disabled  = true;
			document.getElementById('btnResetar').disabled  = false;
			document.getElementById('btnPausar').disabled  = false;
			this.minuto = document.getElementById('min').value;
			this.segundo = document.getElementById('seg').value;
			
			document.getElementById('mostrarValor').classList.remove('mostrarValor');
			document.getElementById('mostrarValor').classList.add('mostrarValor2');
			document.getElementById('exibe').classList.remove('Classexibe');
			document.getElementById('exibe').classList.add('Classexibe2');
			
		}else{
			if(this.segundo == 0 && this.minuto != 0){
				this.segundo = 59;
				this.minuto--;
			}else{
				this.segundo--;
			}
			if(this.minuto == 0 && this.segundo == 0){
				document.getElementById('min').readOnly = false;
				document.getElementById('seg').readOnly = false;
				document.getElementById('btnIniciar').disabled  = false;
				document.getElementById('btnResetar').disabled  = true;
				document.getElementById('btnPausar').disabled  = true;
				this.mostrarValor.value = "00:00";
				
				document.getElementById('mostrarValor').classList.remove('mostrarValor2');
				document.getElementById('mostrarValor').classList.add('mostrarValor');
				document.getElementById('exibe').classList.remove('Classexibe2');
				document.getElementById('exibe').classList.add('Classexibe');
			
				clearTimeout(this.contador);
				return;
			}	
			
			novoMinuto = null;
			novoSegundo = null;
			if(this.minuto <= 9){
				novoMinuto = "0" + this.minuto;
			}else{
				novoMinuto = this.minuto;
			}
			if(this.segundo <= 9){
				novoSegundo = "0" + this.segundo;
			}else{
				novoSegundo = this.segundo;
			}
			this.mostrarValor.value = novoMinuto + ":" + novoSegundo;
		}
	}
	clearTimeout(this.contador);
	this.contador = setTimeout('IniciarCronometro(evento)', 1000);
}

function validarNumero(valor){
	return !isNaN(parseFloat(valor)) && isFinite(valor);
}



function PausarCronometro(){
	if(document.getElementById('btnPausar').value=="PAUSAR"){
		document.getElementById('btnPausar').value = "VOLTAR";
		this.evento = "pause";
	}else{
		document.getElementById('btnPausar').value = "PAUSAR";
		this.evento = "start";
	}
}

function ResetarCronometro(){
	document.getElementById('min').readOnly = false;
	document.getElementById('seg').readOnly = false;
	document.getElementById('btnIniciar').disabled  = false;
	document.getElementById('btnResetar').disabled  = true;
	document.getElementById('btnPausar').disabled  = true;
	document.getElementById('btnPausar').value = "PAUSAR";
	this.mostrarValor.value = "00:00";

document.getElementById('mostrarValor').classList.remove('mostrarValor2');
	document.getElementById('mostrarValor').classList.add('mostrarValor');
	document.getElementById('exibe').classList.remove('Classexibe2');
	document.getElementById('exibe').classList.add('Classexibe');

	clearTimeout(this.contador);
}
html, body {
	height: 99%;
}
body {
	background-color: #f0f0f0;
}
.mostrarValor{
	text-align: center;
	border:0px solid white;
	font-size: 50pt;
}
.mostrarValor2{
	text-align: center;
	border:0px solid white;
	font-size: 50pt;
	animation: fade 10000ms infinite;
}

.Classexibe{
	text-align:center;
}
.Classexibe2{
	text-align:center;
	animation: fade 10000ms infinite;
}
section {
	width: 450px;
}

.btn {
	
	width:100px;
}


@keyframes fade {
	0% {bakcground-color:white;}
	25% {background-color:orange;}
	50% {background-color:green;}
	75% {background-color:red;}
	100% {background-color:white;}
}
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8"/>
<title>CRONÔMETRO</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript" lang="javascript" src="script.js"></script>
</head>

<body>
	<section>
		<article>
			<fieldset class="Classexibe" id="exibe"><legend>Exibição</legend>
				<p><input class="mostrarValor" type="text" id="mostrarValor" size="2" readonly="readonly" value="00:00"/></p>
			</fieldset>
			<fieldset><legend>Configuração</legend>
				<p><label for="min">Colocar minutos: &nbsp;&nbsp;</label><input type="text" id="min" size="2" maxlength="3"/></p>
				<p><label for="seg">Colocar segundos: </label><input type="text" id="seg" size="2" maxlength="2"/></p>
			</fieldset>
			<fieldset><legend>Comandos</legend>
				<p>
					<input class="btn" type="button" value="INICIAR" id="btnIniciar" onclick="IniciarCronometro('start')" /> 
					<input class="btn" type="button" value="PAUSAR" id="btnPausar" onclick="PausarCronometro()" disabled="disabled" /> 
					<input class="btn" type="button" value="RESETAR" id="btnResetar" onclick="ResetarCronometro()" disabled="disabled" /> 
				</p>
			</fieldset>
		</article>
	</section>
</body>
</html>

  • Hello Saul! Thank you so much for helping me... I was desperate, I started from 0 with the switch and it worked! I really liked your logic! If possible, can you explain the clearTimeout and Parsefloat? Note: The input #showValue has to be size 5, so the time can be viewed completely... Very obg! Saved a lot!

  • clearTimeout cancels setTimeout. I put setTimeout in a global variable to cancel with clearTimeout. Parsefloat() takes the first characters separated by space and converts them into a float (real number). The ideal is to count in milliseconds and this count in milliseconds change the second and the second change the minute. In the example I made, I put the second to change the minute. I say this because if it pauses, there will be a small lag when returning but as I said, it is solved by placing in milliseconds. Hug

Browser other questions tagged

You are not signed in. Login or sign up in order to post.