Skip to content

Latest commit

 

History

History
376 lines (307 loc) · 13.8 KB

File metadata and controls

376 lines (307 loc) · 13.8 KB

Clase 7

Eventos

  • 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
  • Usando Eventos (Tradicional)

    • 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;
     	}
  • Usando Eventos (Callbacks)

    • Multiples funciones por evento
    • Necesidad de compatibilizar para IE8
     	// 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, false);
     			console.info("Listener quitado con exito");
     		} else { // IE8
     			document.detachEvent('onclick', manejadorEventos);
     			console.info("Listener quitado con exito");
     		}
    
     	}
     	
     	// Añadimos Listener
     	if (document.addEventListener){ 
     		document.addEventListener('click', manejadorEventos, false);
     		console.info("Listener añadido con exito");
     	} else if (document.attachEvent){ // IE8
     		document.attachEvent('onclick', manejadorEventos);
     		console.info("Listener añadido con exito");
     	} else {
     		document.onclick = manejadorEventos;
     		console.info("Listener añadido con exito");
     	}
  • Dominando el flujo

  • Gestión vs. Delegación de eventos

    • Gestión (asociar un evento por elemento)
     	<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 (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);
        }

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);
     	})

Eventos (custom)

document.body.addEventListener("eventoCustom", function(e) {
	
	console.info("Detalles del evento: ", e);
	console.info("Información adiccional: ", e.detail);
	e.detail.metodo1();
});

var miEvento = new CustomEvent("eventoCustom", {
  detail: {
    dato1: "Hola!",
    metodo1: function(){
        console.log(this.dato1);
    }
  }
});

document.body.dispatchEvent(miEvento);

Ejercicios

1 - Reorganizar la lista de profesores de Fictizia por nombre y apellidos (alfabético)

Solución Parcial

	var profesoresData = "";
	var profesores = Array.prototype.slice.call(document.querySelectorAll('#teachersList > li'));
	
	profesores.sort(function (a, b) {
	    if (a.innerText < b.innerText)
	        return -1;
	    if (a.innerText > b.innerText)
	        return 1;
	    return 0;
	});
	
	profesores.forEach(function(profesor){
	  profesoresData += profesor.outerHTML;
	})
	
	document.getElementById('teachersList').innerHTML = profesoresData;

Solución Total

	//@see: https://davidwalsh.name/sorting-strings-accented-characters
	var profesoresData = "";
	var profesores = Array.prototype.slice.call(document.querySelectorAll('#teachersList > li'));
	
	profesores.sort(function (a, b) {
	    return a.innerText.localeCompare(b.innerText);
	});
	
	profesores.forEach(function(profesor){
	  profesoresData += profesor.outerHTML;
	})
	
	document.getElementById('teachersList').innerHTML = profesoresData;

2 - Saca una lista de los cursos disponibles en Fictizia en las 4 areas de formación y conviertelo en Markdown. Características:

  • Cada Bloque de cursos debe estar identificado por el título correspondiente.
  • Cada curso debe contener el enlace al mismo y especificar el número de horas entre parentesis.
	// Simular el Click (Opcional)
	document.getElementById('web_Tab').click();
	
	var areas = document.querySelectorAll('#areas > section');
	var markdown = "# Cursos de Fictizia\n\n";
	
	for (var i = 0; areas.length > i; i++) {
	
	    var area = areas[i].querySelectorAll('li > a');
	    markdown += "## " + areas[i].querySelector('h2').innerText.trim() + "\n\n";
	    markdown += "**Total de cursos: " + area.length + "**\n";
	  
	    for (var j = 0; area.length > j; j++) {
	            var link = area[j].getAttribute("href");
	            var horas = area[j].querySelector(".contextualInfo").innerText.trim();
	                horas = horas.replace("Curso de ", "").replace("Workshop de ").replace("Master de ", "").replace("undefined", "");
	            var titulo = area[j].querySelector("strong").innerText.trim();
	            var curso = "- [" + titulo + " (" + horas + ")](" + link + ")\n";
	            markdown += curso;
	    }
	    markdown += "\n\n"
	}
	
	console.log(markdown);
  • Respuesta esperada (consola):
	# Cursos de Fictizia
	
	## Cursos de Diseño interactivo & Desarrollo Web
	
	**Total de cursos: 13**
	- [Master en Diseño de interfaz y Front-end con HTML5, CSS3 y jQuery (150 horas)](http://www.fictizia.com/formacion/master_interfaz_frontend_html5_css3_jquery)
	- [Curso de Diseño de interfaz en proyectos Web, Apps y Smart TV (45 horas)](http://www.fictizia.com/formacion/curso_diseno_interfaz_web_apps_smart_tv)
	- [Curso de JavaScript para desarrolladores web (45 horas)](http://www.fictizia.com/formacion/curso_javascript)
	- [Curso de JavaScript Avanzado para desarrolladores Front-end (72 horas)](http://www.fictizia.com/formacion/curso_javascript_avanzado)
	- [Curso de Node.js para desarrolladores Front-end (24 horas)](http://www.fictizia.com/formacion/curso_nodejs)
	- [Curso de AngularJS (30 horas)](http://www.fictizia.com/formacion/curso_angularjs)
	- [Curso de Maquetación web con HTML5 y CSS3 (60 horas)](http://www.fictizia.com/formacion/curso_frontend_html5_css3)
	- [Curso de JQuery para maquetadores web (36 horas)](http://www.fictizia.com/formacion/curso_programacion_jquery)
	- [Curso de Wordpress esencial (24 horas)](http://www.fictizia.com/formacion/wordpress_esencial)
	- [Curso de WordPress (45 horas)](http://www.fictizia.com/formacion/curso_wordpress_profesionales)
	- [Curso de Programación PHP (45 horas)](http://www.fictizia.com/formacion/curso_php_mysql)
	- [Curso de PHP Avanzado con Laravel (36 horas)](http://www.fictizia.com/formacion/curso-laravel-php-avanzado)
	- [Curso de React + Redux (30 horas)](http://www.fictizia.com/formacion/curso-react-js-redux)
	
	## Cursos de Producción 3D & Efectos visuales
	...

3 - Hagamos la web del Metro más divertida.

  • Saca el estado actual de todas las líneas del metro de Madrid por consola.
	var lineas = document.querySelectorAll('.bloquet');
	
	for (var i = 0; i < lineas.length; i++) {
	  var estado = lineas[i].querySelector('.circulacion > .txt > a');
	  
	  if(!estado) estado = lineas[i].querySelector('.circulacion > .r > a');
	  
	  if(estado) console.log(estado.innerText.trim());
	  
	}

4 - Diseña un script que sustituya todas las imágenes de las entradas de Tecnología del Mundo Today por imágenes dummy de gatitos.

		var imagenes = document.querySelectorAll('.td-module-thumb img');
		var imagenesLog = [];
		for(var i = 0; i < imagenes.length; i++){
			var url = document.querySelectorAll('.td-module-thumb img')[i].src;
			var ancho = document.querySelectorAll('.td-module-thumb img')[i].width;
			var alto = document.querySelectorAll('.td-module-thumb img')[i].height;
			var sustituto = "http://lorempixel.com/"+ancho+"/"+alto+"/cats";
			var datos = [url, ancho, alto, sustituto]
			imagenesLog.push(datos);
			document.querySelectorAll('.td-module-thumb img')[i].src = sustituto;
		}

5 - Diseña un script que agrupe todos los titulares, sus autores y categorias dentro de Genbeta:dev y luego vacíe el html para cargar una lista hecha por nosotros con la información previamente recolectada.

	var datos = [];
	var plantilla = "";
	
	for(var i = 0; i < document.querySelectorAll(".article-home-header a").length -1; i++){
		var autor;
		var titular;
		var categorias;
	
		// Autor 
		if(document.querySelectorAll(".article-author a")[i]){
			autor = document.querySelectorAll(".article-author a")[i].innerHTML
		} else {
	 		autor = "Desconocido"
		}
	
		// Titular
		if(document.querySelectorAll(".article-home-header a")[i]){
			titular = document.querySelectorAll(".article-home-header a")[i].innerHTML
		} else {
			titular = "Sin título"
		}
	
		// Categorias
		if(document.querySelectorAll(".article-category a")[i]){
			categorias = document.querySelectorAll(".article-category a")[i].innerHTML
		} else {
			categorias = "Sin categorizar"
		}
	
		datos.push([ autor, titular, categorias]);
	
		plantilla += '<h1>Titular: '+titular+'</h1>';
		plantilla += '<h3>Autor: '+autor+'</h3>';
		plantilla += '<p>Categoria: '+categorias+'</p>';
	};
	
	document.body.innerHTML = plantilla;