Skip to content

Latest commit

 

History

History
338 lines (285 loc) · 13.4 KB

File metadata and controls

338 lines (285 loc) · 13.4 KB

shieldsIO shieldsIO shieldsIO

WideImg

Máster en Programación FullStack con JavaScript y Node.js

JS, Node.js, Frontend, Backend, Firebase, Express, Patrones, HTML5_APIs, Asincronía, Websockets, Testing

Clase 14

Eventos: Funcionamiento

Soporte

  • Podemos escuchar eventos y enlazar funciones (event handler) img_pro_bu

Demo

Propagación:

  • Capturing desde document hasta el elemento
  • Target impacta el elemento
  • Bubbling sube desde el elemento hasta document

Eventos: Usando Eventos con onclick

Solo una función por evento

	<button onclick="cambiarFondo()">Cambia el fondo</button>
	function cambiarFondo() {
		// color = 'rgb(0-255,0-255,0-255'
		var color = 'rgb(' + Math.floor((Math.random() * 255))+ ',';
		color += Math.floor((Math.random() * 255)) + ',';
		color += Math.floor((Math.random() * 255)) + ')';
		document.body.style.backgroundColor= color;
		console.info("Nuevo color:", color);
	}

Usando Eventos (actualidad):

  • Usando Eventos (Callbacks)

    • Multiples funciones por evento
    • Necesidad de compatibilizar para IE8
  • Propiedades

     	// Callback - Manejador de Eventos
     	function manejadorEventos(elEvento) {
     	  	// Compatibilizar el evento
     	  	var evento = elEvento || window.event;
     	  	// Imprimir detalles
     	  	console.log("-----------------------------")
     	  	console.log("Type: "+evento.type); // Tipo
     	  	console.log("Bubbles: "+evento.bubbles);
     	  	console.log("Cancelable: "+evento.cancelable);
     	  	console.log("CurrentTarget: ", evento.currentTarget);
     		console.log("DefaultPrevented: "+evento.defaultPrevented);
     		console.log("EventPhase: "+evento.eventPhase);
     		console.log("Target: ", evento.target);
     		console.log("TimeStamp: "+evento.timeStamp);
     		console.log("IsTrusted: "+evento.isTrusted); // true - Usuario o false - Script
     		console.log("=============================")
     		// Desactivamos
     		if (document.removeEventListener){ 
     			document.removeEventListener('click', manejadorEventos);
     			console.info("Listener quitado con exito");
     		} else { // IE8
     			document.detachEvent('onclick', manejadorEventos);
     			console.info("Listener quitado con exito");
     		}
     	}
     	// Añadimos Listener
     	document.addEventListener('click', manejadorEventos);
  • Métodos:

    • .addEventListener() Añadir un evento a un elemento del DOM:
     document.body.addEventListener('click', function (e) {
         var color = 'rgb(' + Math.floor((Math.random() * 255))+ ',';
         color += Math.floor((Math.random() * 255)) + ',';
         color += Math.floor((Math.random() * 255)) + ')';
         document.body.style.backgroundColor= color;
         console.info("Nuevo color:", color);
     });
    • .attachEvent() Añadir un evento a un elemento del DOM (<= IE8):
     document.attachEvent('onclick', function (e) {
         var color = 'rgb(' + Math.floor((Math.random() * 255))+ ',';
         color += Math.floor((Math.random() * 255)) + ',';
         color += Math.floor((Math.random() * 255)) + ')';
         document.body.style.backgroundColor= color;
         console.info("Nuevo color:", color);
     });
    • .removeEventListener() Elimina un evento previamente añadido:
     function cambiarColor (){
         var color = 'rgb(' + Math.floor((Math.random() * 255))+ ',';
         color += Math.floor((Math.random() * 255)) + ',';
         color += Math.floor((Math.random() * 255)) + ')';
         document.body.style.backgroundColor= color;
         console.info("Nuevo color:", color);
     }
     
     document.body.addEventListener('click', cambiarColor);
     document.body.removeEventListener('click', cambiarColor);
    • .detachEvent() Elimina un evento previamente añadido (<= IE8):
     function cambiarColor (){
         var color = 'rgb(' + Math.floor((Math.random() * 255))+ ',';
         color += Math.floor((Math.random() * 255)) + ',';
         color += Math.floor((Math.random() * 255)) + ')';
         document.body.style.backgroundColor= color;
         console.info("Nuevo color:", color);
     }
     
     document.body.attachEvent('onclick', cambiarColor);
     document.body.detachEvent('onclick', cambiarColor);
    • .dispatchEvent() Lanza un evento manualmente:
     document.body.addEventListener('click', function (e) {
         var color = 'rgb(' + Math.floor((Math.random() * 255))+ ',';
         color += Math.floor((Math.random() * 255)) + ',';
         color += Math.floor((Math.random() * 255)) + ')';
         document.body.style.backgroundColor= color;
         console.info("Nuevo color:", color);
     });
     
     var lanzadorEventos = new Event('click');
     document.body.dispatchEvent(lanzadorEventos);

Detalles de un evento

document.body.addEventListener("click", detallesEvento, false);
document.body.addEventListener("keyup", detallesEvento, false);


function detallesEvento (evento) {
    console.group("Manejador de Eventos");
    	console.log("-----------------------------");
    	for (var propiedad in evento){
    		console.log("evento["+propiedad+"]="+evento[propiedad])
    	}
        console.log("=============================");
    console.groupEnd();
}

Referencia de event.type:

  • Ratón

    • click Cuando... se hace click de ratón
    • dblclick Cuando... se hace doble click de ratón
  • Teclado

    • keydown Cuando... se presionó la tecla
    • keypress Cuando... se presiona la tecla
    • keyup Cuando... se deja de pulsar la tecla
  • Más eventos

Gestionando el flujo

  • Deteniendo el flujo:
    • .preventDefault() evita el comportamiento por defecto (ex: Link -> nueva URL)
    • .stopPropagation() evita la propagación por el DOM (bubble) pero permite la acción por defecto.

Gestión de Eventos:

	<ul id="miNav">
		 <li><a href="#nosotros">¿Quienes Somos?</a></li>
		 <li><a href="#objetivos">Los objetivos</a></li>
		 <li><a href="#equipo">Nuestro Equipo</a></li>
		 <li><a href="#detalles">Más detalles</a></li>
		 <li><a href="#contacta">Contactanos</a></li>
	</ul>
   var miNav = document.getElementById("miNav");
   var miNavLinks = miNav.getElementsByTagName("a");
   for (var i = 0; i < miNavLinks.length; i++) {
     miNavLinks[i].onclick = function(){
        console.info(this.innerHTML);
     }
   }

Delegación de eventos:

Delegación (asociar un único evento al padre de los elementos)

	<ul id="miNav">
		 <li><a href="#nosotros">¿Quienes Somos?</a></li>
		 <li><a href="#objetivos">Los objetivos</a></li>
		 <li><a href="#equipo">Nuestro Equipo</a></li>
		 <li><a href="#detalles">Más detalles</a></li>
		 <li><a href="#contacta">Contactanos</a></li>
	</ul>
   var miNav = document.getElementById("miNav");
   miNav.onclick = function(evento){
      var evento = evento || window.event;
      var elemento = evento.target || evento.srcElement;
      console.info(elemento.innerHTML);
   }

Creación de Eventos Personalizados

	var evento = new Event('miEventoInventado');
	
	document.body.addEventListener('miEventoInventado', function (e) {
		console.info(e); // {isTrusted: false}
	});
	
	document.body.dispatchEvent(evento);

Programación dirigida a eventos

La programación dirigida por eventos es un paradigma de programación en el que tanto la estructura como la ejecución de los programas van determinados por los sucesos que ocurran en el sistema, definidos por el usuario o que ellos mismos provoquen.

Para entender la programación dirigida por eventos, podemos oponerla a lo que no es: mientras en la programación secuencial (o estructurada) es el programador el que define cuál va a ser el flujo del programa, en la programación dirigida por eventos será el propio usuario —o lo que sea que esté accionando el programa— el que dirija el flujo del programa. Aunque en la programación secuencial puede haber intervención de un agente externo al programa, estas intervenciones ocurrirán cuando el programador lo haya determinado, y no en cualquier momento como puede ser en el caso de la programación dirigida por eventos. Wikiwand

  • Ejemplo:
     	var eventos = {
     		agregar: null,
     		quitar: null,
     		manejador: function(evento) {
     	        console.group("Manejador de Eventos");
     		        console.log("-----------------------------");
     	            console.log("Type: " + evento.type); // Tipo
     	            console.log("Bubbles: " + evento.bubbles); // sube por el DOM
     	            console.log("Cancelable: " + evento.cancelable);
     	            console.log("CurrentTarget: ", evento.currentTarget);
     	            console.log("DefaultPrevented: " + evento.defaultPrevented);
     	            console.log("EventPhase: " + evento.eventPhase);
     	            console.log("Target: ", evento.target);
     	            console.log("TimeStamp: " + evento.timeStamp);
     	            console.log("IsTrusted: " + evento.isTrusted); // true - Usuario o false - Script
     	            console.log("=============================");
     	        console.groupEnd();
     	    }
     	}
     	
     	// Init-time branching (Patrón)
     	if (typeof window.addEventListener === 'function') {
     	    eventos.agregar = function(el, type, fn) {
     	    	el.addEventListener(type, fn, false);
     		};
     	    eventos.quitar = function(el, type, fn) {
     	    	el.removeEventListener(type, fn, false);
     	    };
     	} else { // Soporte para IE8
     	    eventos.agregar = function(el, type, fn) {
     	        el.attachEvent('on' + type, fn);
     	    };
     	    eventos.quitar = function(el, type, fn) {
     	        el.detachEvent('on' + type, fn);
     	    };
     	}
     	
     	eventos.agregar(document.body, 'click', function (e) {
     		var color = 'rgb(' + Math.floor((Math.random() * 255))+ ',';
     		color += Math.floor((Math.random() * 255)) + ',';
     		color += Math.floor((Math.random() * 255)) + ')';
     		document.body.style.backgroundColor= color;
     		console.info("Nuevo color:", color);
     	})

Depuración de Eventos en Consola

monitorEvents(document.body, "click");		// info de los eventos
unmonitorEvents(document.body);				// Dejar de seguir los eventos del elemento
unmonitorEvents(document.body, "click");	// Dejar de seguir los eventos de un tipo especifico sobre el elemento

Buenas prácticas

Lo esencial

  • NO tener demasiadas dependencias (ficheros y librerias)
  • NO tener mucha manipulación del DOM
  • Gestionar los eventos bien, haciendo uso de patrones
  • Pensar siempre en la Experiencia del usuario y contar con patrones para ello
  • OFFLINE First, piensa en reducir la carga de la multimedia siempre que puedas
  • Estructura bien tu código
  • Usa linters para todo (HTML, CSS y JS)
  • Encola y empaqueta los cambios del DOM
  • Minifica, ofusca y comprime siempre que puedas los ficheros
  • Valida las accioens del usuario usando js cuando lo necesites
  • Considera el FrontEnd como una zona de riesgo y piensa en la seguridad primero
  • Utiliza naming para tu CSS
  • Utiliza plugins y herramientas para calidar tu proyecto en todo momento
  • Primero carga el CSS (Final del head) y despues JS (Final del body)
  • Usa CDNs o carga tus dependencias de forma local

Recursos

Ejercicios

1 - Realiza una pagina web que muestre la cuenta atrás para terminar el master en días, horas, minutos y segundos. Objetivos Adicionales:

  • Además debería de seguir actualizando la cuenta atrás de manera dinámica.
  • Los datos horarios siempre deben mostrarse con dos dígitos, añadiendo un cero a la izquierda cuando sea necesario.