Cuenta regresiva: javascript

Codigo javascript

El código javascript no es más que la traducción del diagrama de bloques que hemos preparado en la sección del boceto o pasos previos del desarrollo de este proyecto.

En el diagrama verás algunos pasos que en el código son funciones. Es posible escribir todo o casi todo el script en una sola función, pero es preferible romper el código en módulos más pequeños que nos facilitará posteriores modificaciones o ampliaciones. Y además es más didáctico.

Recuerda: estrategia divide y vencerás.

Procura comentar los pasos que veas más oscuros, aquí muchos comentarios están escritos en la página.

El funcionamiento del contador comienza con una llamada a la función iniciarContador() cuyo argumento es un nombre para el bloque contador.

En esta función calculamos la fecha actual comno el objeto Date(), para la fecha final se extrae el dato del bloque contador, leerFinal() .

Ambas fechas se traducen a milisegundos desde la fecha de referencia que sua Javascript (1 de Enero de 1990). El intervalo de tiempo esla diferencias entre esos valores, que traducimos a segundos dividiendo por 1000.

Usamos un objeto con el valor del intervalor y un campo para el temporizador que se encargará de ir descontando 1 seg al intervalo de tiempo, con setInterval().

´La función setInteval(callback, tiempo, [argumentos]) usa como primer argumento el nombre de la función que será llamda a itnervalos de tiempo dados por el segundo argumento. Además puede llevar otros argumentos que se pasarán a la función callback.

En este caso la función contar se llama cada 1000 milisegundos (un segundo) y se la pasa como argumento el bloque con el propio temporizador y el intervao de tiempo.

Los cambios hechos en un argumento tipo objeto dentro de una funcion se mantienen cuando esta termina. Es la fomra de pasar argumentos por referencia en javascript

//Elemento contador

iniciarContador('micontador');

//Inicia la cuenta atrás

//bloque es el id del bloque usado para alojar el contador regresivo.

function iniciarContador(bloque){

   let hoy = new Date();

   let ini = hoy.valueOf();

   let fin = leerFinal(bloque)

   let tiempo = Math.floor((fin - ini)/1000); //pasar a segundos enteros)

   let obContador = {timer:null, "tiempo":tiempo};

   contar(obContador, bloque); //para evitar el delay inicial de 1 segundo

   obContador.timer = setInterval(contar, 1000, obContador, bloque);

   }

//Decrementa el tiempo hasta la fecha final

//Argumento: objeto con temporizador y el tiempo restante

 function contar(contador, bloque){

   let partes = [];

   if(contador.tiempo <= 0){

      clearInterval(contador.timer);

      contador.tiempo = 0;  //por si la fecha final ha pasado

   }

   else{

      contador.tiempo--;

   }

  partes = formatTiempo(contador.tiempo);

  mostrarTiempo(partes, bloque);

}

Este es el disagrama de fujo traducido a códio, ahora hay que detallar un poco, con las funciones auxiliares.

Para mostrar en pantalla los millisegundos se deben traducir a dias, horas minutos y segundos. Recuerda que un día son 24 horas, 1 hora son 60 minutos y 1 minutos son 60 segundos.

Creamos la función dividir(a, b) que devuelve el cociente entero y el resto de una división para los cambios de unidades. El uso es simple: 70 segundos si deivido por 60 para saber cuantos minutos son obtengo como parte entera 1 y me quedan 10 segundos de resto. Y como ves 70 segundos son 1 minutos (60 segundos) y sobran 10 segundos.

//Convierte el tiempo restante en partes dias, horas, minutos, segundos

function formatTiempo(tiempo){

   let dias, horas, minutos, segundos, partes;

   [minutos, segundos] = dividir(tiempo, 60);

   [horas, minutos] = dividir(minutos, 60);

   [dias, horas] = dividir(horas, 24);

   partes = [dias, horas, minutos, segundos];

   return partes;

}

//divide números enteros devuelve [cociente, resto]

function dividir(num, den){

   num = Math.floor(num);

   let coc = Math.floor(num/den);

   let resto = num % den;

   return [coc, resto];

}

Y solo queda la interfaz con el html. Una función se encarga de leer la fecha del bloque contador, leerFinal(), la fecha debe indicarse en un data-set con el formato año/mes/dia. Y mostrarTiempo() se encargará de colocar los números en los bloques <span> dentro del bloque contador, deberán ser bloques span con clase dig

//Poner en la página web

//Argumento : array dias,horas,minutos,segundos

//Partes estarán dentro del bloque contador

function mostrarTiempo(partes, bloque){

   let bloques = document.querySelectorAll("#"+bloque+" .dig span");

   for(let i=0; i < bloques.length; i++){

      bloques[i].innerHTML = partes[i].toString().padStart(2,0);

   }

 }

//Lee el valor de fecha final desde un elemento con id = contador

//devuelve fecha final como valor

//formato de fecha año-mes-dia o año/mes/dia

function leerFinal(bloque){

   let fecha;

   let milisec = 0;

   let datos = document.getElementById(bloque);

   datos = datos.dataset.final;

   fecha = new Date(datos);

   if (!isNaN(fecha.valueOf())){

      fecha = new Date(fecha);

     milisec = fecha.valueOf();

   }

   return milisec;

 }

 

Comentarios

El código Javascript para este poyecto es fundamentalmente la traducción del intervalo de tiempo en milisegundos a dias , horas, minutos y segundos.

En este proyecto el código condiciona o define como se colocarán los datos de tiempo en página web.

Los estilos y situación del widget en la página se definen en el diseño del documento html y los estilos CSS