Controle de ociosidade

Tenho este código:

<html>

<head>
	<script src="http://code.jquery.com/jquery-1.9.1.min.js">// O código está todo comentado!</script>
	<script type="text/javascript">
		var tempo = new Number();
		// Tempo em segundos
		tempo = 300;
		
		function startCountdown(){
			// Se o tempo não for zerado
			if ((tempo - 1) >= 0) {
				// Pega a parte inteira dos minutos
				var min = parseInt(tempo/60);
				
				// Calcula os segundos restantes
				var seg = tempo%60;
				
				// Formata o número menor que dez, ex: 08, 07, ...
				if (min < 10) {
					min = "0"+min;
					min = min.substr(0, 2);
				}
				
				if (seg <=9) {
					seg = "0"+seg;
				}
				
				// Cria a variável para formatar no estilo hora/cronômetro
				horaImprimivel = '00:' + min + ':' + seg;
				
				//JQuery pra setar o valor
				$("#sessao").html(horaImprimivel);
				
				// Define que a função será executada novamente em 1000ms = 1 segundo
				setTimeout('startCountdown()', 1000);
				
				// diminui o tempo
				tempo--;
				
			// Quando o contador chegar a zero faz esta ação
			} else {
				window.open('../controllers/logout.php', '_self');
			}
		}
		
		// Chama a função ao carregar a tela
		startCountdown();
	</script>
</head>

<body>
	<div>A conexão se encerra em <span id="sessao">Carregando...</span>&nbsp;min.</div>
	<span id="detecta"></span>
</body>

<footer>
</footer>

</html>

preciso que a pagina perceba o atividade de qualquer tecla para reiniciar a contagem, NÃO PODE atualizar a pagina.
Pelo amor de Deus ja tentei varias implementações, até evento keypressed e não consegui o resultado desejado. me ajudem por favor…!!!

Não consigo testar no momento, mas verifique se isso lhe ajuda:

Se a ideia é detectar qualquer tecla que for pressionada, use o evento keydown.

Segundo a documentação, o evento keypress está deprecated e não é mais recomendado. Já o evento keydown é descrito como:

O evento keydown é disparado quando uma tecla é pressionada. Diferente do evento obsoleto keypress, o keydown é disparado para todas as teclas, independente de produzirem ou não um caractere.

Enfim, então basta fazer o seguinte:

  • assim que a página carregar, você inicia a contagem
  • se a contagem zerou, chama window.open
  • se não zerou, mostra quanto tempo falta, atualiza a contagem e faz uma nova verificação
  • se em qualquer momento uma tecla for pressionada, cancela a verificação atual e reinicia a contagem

Seria algo assim:

<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>teste timeout</title>
    <script type="text/javascript">
        var timeoutSegundos = 300; // expira em 300 segundos
        var sessao;
        var currentTimeout = null;

        function verificaExpiracao(segundos) {
            if (segundos <= 0) {
                sessao.textContent = '00:00:00';
                window.open('../controllers/logout.php', '_self');
            } else {
                // formata o timeout em HH:MM:SS
                // Math.floor é melhor que parseInt para arredondar: https://pt.stackoverflow.com/q/506307/112052
                var horas = Math.floor(segundos / 3600).toString().padStart(2, '0');
                var seg = segundos % 3600;
                var min = Math.floor(seg / 60).toString().padStart(2, '0');
                seg = (seg % 60).toString().padStart(2, '0');
                sessao.textContent = `${horas}:${min}:${seg}`;

                // verifica novamente, diminuindo 1 segundo do timeout
                currentTimeout = setTimeout(() => verificaExpiracao(segundos - 1), 1000);
            }
        }

        document.addEventListener('DOMContentLoaded', function() { // só executa quando a página carregar
            sessao = document.querySelector('#sessao'); // busca o elemento uma vez só, assim que a página carregar
            verificaExpiracao(timeoutSegundos); // inicia a contagem
        });

        document.addEventListener('keydown', function() {
            // se pressionar qualquer tecla, recomeça a contagem
            // mas antes verifica se já tinha algum timeout executando
            if (currentTimeout) {
                clearTimeout(currentTimeout);
            }
            // reinicia a contagem, usando o tempo total
            verificaExpiracao(timeoutSegundos);
        })
    </script>
</head>
<body>
    <div>A conexão se encerra em <span id="sessao"></span></div>
</body>
</html>

Usei o evento DOMContentLoaded para garantir que a verificação só começa depois que a página carregar.

Também tomei o cuidado de limpar o timer atual, caso exista (usando clearTimeout). Se eu não fizer isso, aconteceria o seguinte:

  • contagem começa com 300 segundos, chama setTimeout para verificar de novo em 1 segundo (ou seja, criou um timer)
  • depois de um tempo, uma tecla é pressionada
  • cria outro timer de 300 segundos
  • ou seja, agora tem 2 timers ativos, e ambos irão rodar até zerar (vai chamar window.open duas vezes)

Usando clearTimeout, eu garanto que só vai ter um timer ativo (o mais recente).

Também usei Math.floor, que é o ideal para arredondar para baixo. parseInt até “funciona”, mas ele pode falhar em vários casos.

Deu certo, obrigado hugokotsubo
Tem tempo que não trabalho com o javascript ja a uns 3 anos. Tava esquecendo.