Creando un componente reutilizable con Javascript

Vamos a crear un cronómetro que se pueda reuilizar en cualquier parte de nuestro proyecto como si se tratara de un plugin.

autor Rodríguez Patiño, Eduardo
publicado
visitas 6,960

En esta entrada vimos como crear un cronómetro con jQuery, ahora vamos a crear el mismo cronómetro sin usar jQuery (si, si, estoy con la filosofía Only JS) y que se pueda reuitilizar en cualqueir parte de nuestro aplicativo.

En estos casos debemos expandir nuestra cerebro y pensar que todo es escalable, TODO. Porque esto va a permitir crear un código más ordenado, que sea más fácil de mantener y hacerlo escalar a un futuro.

CSS

Nuestro CSS debe ser escalable, por lo tanto deberá usar clases en vez de ID y le agregamos un prefijo para que no choque con otra clase que pueda llamarse igual.

.chrono{width:400px;margin:auto;background:#eee;padding:10px;border:1px solid #222;margin-bottom:30px;}
.chrono-container{display:flex;}
.chrono-container div{flex-direction:column;padding:20px;width:100%;text-align:center;font-size:2em;}
.chrono-start{border-radius:2px;padding:10px;display:block;width:100%;font-size:1.4em;border:1px solid #222;background:#222;color:#eee;cursor:pointer;}
.chrono-start:hover{background:#333;color:#eee;}

HTML

La maquetación base es la que mostramos líneas abajo. Cada cronometro le agregamos un contenedor y un ID para que nuestro javascript lo capture y pueda interactuar con este.

<div id="chrono-a" class="chrono">
    <div class="chrono-container">
        <div class="chrono-hour">00</div>
        <div class="chrono-divider">:</div>
        <div class="chrono-minute">00</div>
        <div class="chrono-divider">:</div>
        <div class="chrono-second">00</div>                
    </div>
    <button class="chrono-start">Comenzar</button>
</div>

<div id="chrono-b" class="chrono">
    <div class="chrono-container">
        <div class="chrono-hour">00</div>
        <div class="chrono-divider">:</div>
        <div class="chrono-minute">00</div>
        <div class="chrono-divider">:</div>
        <div class="chrono-second">00</div>                
    </div>
    <button class="chrono-start">Comenzar</button>
</div>

<div id="chrono-c" class="chrono">
    <div class="chrono-container">
        <div class="chrono-hour">00</div>
        <div class="chrono-divider">:</div>
        <div class="chrono-minute">00</div>
        <div class="chrono-divider">:</div>
        <div class="chrono-second">00</div>                
    </div>
    <button class="chrono-start">Comenzar</button>
</div>

<div id="chrono-d" class="chrono">
    <div class="chrono-container">
        <div class="chrono-hour">00</div>
        <div class="chrono-divider">:</div>
        <div class="chrono-minute">00</div>
        <div class="chrono-divider">:</div>
        <div class="chrono-second">00</div>                
    </div>
    <button class="chrono-start">Comenzar</button>
</div>

Javascript

He creado un archivo chrono.js que contiene todo el script para que levante el cronómetro.

var Chrono = function(id){
    var target = {};
    var isRunning = false;
    var timer;    
    var time = {
        hour: 0,
        second: 0,
        minute: 0
    };

    function start(){
        timer = setInterval(function(){
            // seconds
            time.second++;
            if(time.second >= 60)
            {
                time.second = 0;
                time.minute++;
            }      

            // minutes
            if(time.minute >= 60)
            {
                time.minute = 0;
                time.hour++;
            }

            target.hour.innerHTML = time.hour < 10 ? '0' + time.hour : time.hour;
            target.minute.innerHTML = time.minute < 10 ? '0' + time.minute : time.minute;
            target.second.innerHTML = time.second < 10 ? '0' + time.second : time.second;

            console.log('Time elapsed: ' + time.hour + ':' + time.minute + ':' + time.second + ' from ' + id);

            isRunning = true;
        }, 1000);
    }

    function stop()
    {
        isRunning = false;
        clearInterval(timer);
    }

    function init(id){
        target = {
            hour: document.querySelectorAll(id + " .chrono-hour")[0],
            minute: document.querySelectorAll(id + " .chrono-minute")[0],
            second: document.querySelectorAll(id + " .chrono-second")[0],
        };
        
        var _btnStart = document.querySelectorAll(id + " .chrono-start")[0];
        
        _btnStart.addEventListener('click', function(){
            if(!isRunning) {
                _btnStart.innerHTML = 'Detener';
                start();
            }
            else {
                _btnStart.innerHTML = 'Continuar';
                stop();
            }
        })
    }

    init(id);
};
  • Nuestra variable recibe un parámetro, ya que nuestra esta pertenece a una función la cual hemos declarado en el código anterior.
  • Ni bien recibe el parámetro, tenemos una función privada llamada init(id) que se encargará de inicializar el cronometro.
  • Mediante el uso de querySelectorAll identificamos los controles de nuestro cronómetro, donde irá la hora, minuto, segundo y el botón start.
  • A la vez, este método init declara un evento para inicializar o detener el cronómetro cada vez que se haga click.

¿Cómo los inicializo?

Pasandole el ID que contiene a la maquetación del cronómetro.

Chrono('#chrono-a');
Chrono('#chrono-b');
Chrono('#chrono-c');
Chrono('#chrono-d');

Cualquier duda que tengan mi dejan un comentario. Adjunto el código de fuente y el ejemplo online.

- Nuestros cursos -

Curso de October CMS
Curso de TypeScript desde cero
Curso de API RESTFul con Lumen
Curso de Node JS y arquitectura REST
Curso de Microservicios con .Net Core 3+
Curso de PHP 7 y el patrón repositorio