Archivos de la categoría ‘HTML5’

A continuación vamos a ver, mediante una sencilla aplicación, un buen ejemplo de las posibilidades que puede proporcionarnos esta magnífica funcionalidad que trae consigo el estándar HTML5. Dicha aplicación consistirá en la posibilidad de votar nuestras redes sociales favoritas, haciendo uso, claro está, de la operación arrastrar y soltar.
Empecemos con el código html:

<body>
	
	<div id="header">
		<img id="cabecera" src="img/cabecera.png" />
		<h2>Vota tus aplicaciones favoritas</h2>
	</div>
		
	<hr>
		
	<div id="containerVotacion">
			
		<div id="Muy_buena" class="destino verde" ondrop="drop(event)" ondragover="allowDrop(event)" ondragleave="dragLeave(event)">
			<p>Muy buena</p>
		</div>
				
		<div id="Buena" class="destino amarillo" ondrop="drop(event)" ondragover="allowDrop(event)" ondragleave="dragLeave(event)">
			<p>Buena</p>
		</div>
				
		<div id="Regular" class="destino rojo" ondrop="drop(event)" ondragover="allowDrop(event)"	ondragleave="dragLeave(event)">
			<p>Regular</p>
		</div>
			
	</div>
		
	<div id="containerElementos" ondrop="drop(event)" ondragover="allowDrop(event)"	ondragleave="dragLeave(event)">
			
		<img id="facebook" src="img/facebook.png" draggable="true" ondragstart="drag(event)" ondragend="dragEnd(event)" width="64" height="64"/>
		
		<img id="twitter" src="img/twitter.png" draggable="true" ondragstart="drag(event)" ondragend="dragEnd(event)" width="64" height="64"/>
				
		<img id="linkedin" src="img/linkedin.png" draggable="true"	ondragstart="drag(event)" ondragend="dragEnd(event)" width="64" height="64"/>
			
	</div>
		
	<footer id="pie">
		<button id="resultados" onclick="obtenerResultados();">Ver resultados</button>
	</footer>
		
</body>

 

Aquí podemos observar tan solo la parte del “body” del html, para no distraernos con otras líneas de código que ahora no importan.
La imagen dentro del primer div simplemente aparece a modo decorativo. Todos los recursos que se emplean aquí van a estar disponibles a través del enlace a mi repositorio Github que os dejaré al final del artículo.
Vamos a fijarnos en lo importante. Hay dos div contenedores que van a diferenciar la zona disponible para votar, de la que contendrá los iconos de las redes sociales más relevantes, y que estarán disponibles parar ser arrastrados y soltados en la zona de votación que deseemos.
Así pues queda claro que el div con id containerVotación integra a los tres div que equivalen a las votaciones “muy buena”, “buena” o “regular”. Podemos observar que todos estos div tienen tres eventos in line. Veamos qué hacen:

  • ondrop: Controla si en el div se han “soltado” elementos con la propiedad draggable (que pueden ser arrastrados) sobre él. Esto, evidentemente, determina que se trata de una zona drop válida que permite alojar esos elementos provenientes de un drag (“arrastre”). Al hacerlo llamará a la función drop, pasándole como argumento el propio evento.
  • ondragover: Controla que en el div se están arrastrando elementos con la propiedad draggable hacia una zona que permita “soltar” esos elementos. Al hacerlo llamará a la función allowDrop, pasándole como argumento el propio evento.
  • ondragleave: Controla el momento en que un elemento draggable abandona la zona drop donde se encuentra.

El div con id containerElementos dispone de los mismos eventos arriba mencionados. Esto permite que de él se puedan tanto arrastrar como soltar elementos, lo mismo que ocurre con los div contenidos en el div contenedor containerVotación de forma individual.

En su interior cuenta con tres imágenes que se encargan de mostrar los logos de las tres redes sociales más relevantes del momento, las cuales tienen un id correspondiente a la red social en cuestión, y cuyos eventos pasamos a comentar:

  • draggable: Permite que el elemento puede ser “arrastrado” hacia una zona drop válida. Como vemos, se trata de una propiedad que únicamente hay que igualar a true para que funcione sobre el elemento donde estemos declarándola.
  • ondragstart: Este evento se dispara cuando el elemento comienza a ser “arrastrado” desde una zona drop válida.
  • ondragend: El evento se dispara cuando el usuario finaliza el “arrastrado” del elemento sobre una zona drop válida.

Con todo esto, y resumiendo, lo que tenemos es una zona que contiene elementos “arrastrables” y que, a su vez, permite depositar elementos “arrastrados” a nivel general. Lógicamente se trata del div containerElementos y sus img correspondientes. Por otro lado tenemos la zona que contiene a su vez zonas individuales que permiten igualmente depositar elementos “arrastrados” o que se “arrastren” a partir de ellos. Se trara del div containerVotacion y sus correspondientes div con id igual al tipo de nota que queremos otorgar al elemento draggable en cuestión.

Para finalizar, tenemos en el pie de página un botón que será el encargado de obtener los resultados de la votación.

Veamos ahora el código javascript encargado de toda la funcionalidad:

var destino;
var arrastrando;
var ancho;
var alto;
var resultado=new Array();
var resultadoFinal=new Array();

function allowDrop(ev)
{
ev.preventDefault();
destino = devuelveElemento(ev);
destino.style.opacity="0.4";
}

function drag(ev)
{
arrastrando = devuelveElemento(ev);
ancho = arrastrando.width;
alto = arrastrando.height;
arrastrando.style.width=ancho/2+"px";
arrastrando.style.height=alto/2+"px";
var dragIcon = document.createElement('img');
dragIcon.src = 'img/vote.png';
dragIcon.width = 100;
ev.dataTransfer.setDragImage(dragIcon, -10, -10);
ev.dataTransfer.setData("Text", ev.target.id);
}

function dragLeave(ev){
destino.style.opacity="1";
}

function dragEnd(ev){
arrastrando.style.width=ancho+"px";
arrastrando.style.height=alto+"px";
}

function drop(ev)
{
var contenedorUsado = destino.id;
var elementoVotado = arrastrando.id;
resultados(contenedorUsado,elementoVotado);
ev.preventDefault();
destino.style.opacity="1";
var data = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}

function devuelveElemento(ev){
var elemento = document.getElementById(ev.target.id);
return elemento;
}

function resultados(voto,votado){
resultado.push(voto+" "+votado);
}

function obtenerResultados(){

resultadoFinal = sanearResultados();

var ancho= 700;
var alto = 500;
var posicion_x;
var posicion_y;
posicion_x=(screen.width/2)-(ancho/2);
posicion_y=(screen.height/2)-(alto/2);
MiVentana = window.open("","Resultados Drag&Drop HTML5","toolbar=no, location=no, status=no, resizable=no, top="+ posicion_y +", left="+ posicion_x +", width=700, height=500");
MiVentana.document.write('<!DOCTYPE html>\n<head>\n<title>Resultados Drag&Drop HTML5</title>');
MiVentana.document.write('\n<meta charset="utf-8"/>');
MiVentana.document.write('\n<link href="http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz:400,300,200,700&subset=latin,latin-ext" rel="stylesheet" type="text/css">');
MiVentana.document.write('\n<link rel="stylesheet" type="text/css" href="css/estilo.css"/>');
MiVentana.document.write('\n</head>\n<body>\n<div id="header">');
MiVentana.document.write('\n<img id="cabecera" src="img/cabecera.png" />');
MiVentana.document.write('\n<h2>Resultados</h2>\n');
for (var z=0;z<resultadoFinal.length;z++){
MiVentana.document.write(resultadoFinal[z]+"<br>\n");
}
MiVentana.document.write('<br>');
MiVentana.document.write('\n<input type="button" value="Cerrar" onclick="window.close()">');
MiVentana.document.write('\n</div>\n</body>\n</html>');
MiVentana.document.close();
}

function sanearResultados(){

var social = [];
var controlFacebook=0;
var controlTwitter=0;
var controlLinkedin=0;

for (var j=1;j<=resultado.length;j++){

var elemento = resultado[resultado.length-j].toString();

if (elemento.indexOf("Elementos")>0){
continue;
}

if (elemento.indexOf("facebook")>0 && controlFacebook==0){
social.push(elemento);
controlFacebook = 1;
}
if (elemento.indexOf("twitter")>0 && controlTwitter==0){
social.push(elemento);
controlTwitter = 1;
}
if (elemento.indexOf("linkedin")>0 && controlLinkedin==0){
social.push(elemento);
controlLinkedin = 1;
}

}

return social;
}

 
Bien, vayamos por partes.
Al principio declaramos unas cuantas variables a nivel global. Dos de ellas arrays.
Todas las funciones que se llaman cuando se desencadena algún evento ya visto, tienen como parámetro ev, es decir, el propio origen del evento mismo.

La función allowDrop, que se dispara cuando un elemento draggable pasa por una zona drop válida, lo que hace es guardar en la variable destino cuál es el elemento (en nuestro caso un div) sobre el que se está arrastrando un elemento draggable (en nuestro caso los img). Para ello se llama a la función devuelveElemento pasándole a su vez el origen del evento recibido. También damos una opacidad para que el contenedor drop disponible sobre el que se pasa, nos informe de que está listo para recibir el elemento draggable.

La función drag se dispara cuando un elemento draggable comienza a ser “arrastrado”. Para conocer de cúal se trata aprovechamos de nuevo la función devuelveElemento y lo guardamos en la variable creada para ello. Seguidamente hayamos su alto y ancho para asignarle la mitad de ambos durante el efecto de “arrastrado”. Además, creamos dinámicamente un pequeño icono bajo el elemento “arrastrado” para indicar al usuario que se está llevando a cabo el proceso. Para añadirlo definitivamente a nuestro elemento en proceso de “arrastrado”, debemos llamar al método dataTransfer, primero seteando su posición respecto al elemento “arrastrado” y después haciendo lo propio con el tipo de dato.

La función dragLeave se ejecuta cuando un elemento draggable deja de estar sobre una zona drop válida. En ese caso lo único que hacemos es eliminar la opacidad que tenga el contenedor drop sobre el que se acaba de terminar de pasar.

La función dragEnd devuelve el tamaño completo al elemento “arrastrado” cuando éste termina de “aterrizar” sobre una zona drop válida.

La función drop es llamada cuando una zona drop válida termina de recibir un elemento draggable. En ese momento obtenemos qué zona drop de nuestra aplicación está recibiendo el elemento y cuál es ese elemento (en nuestro caso el img de alguna red social). Esto ya lo sabemos gracias a las variables globales destino y arrastrando, que ya han guardado anteriormente esa información durante los pasos previos. Una vez los conocemos, llamamos a la función resultados pasándole esos datos. Lo que hace es añadirlos a un array, tal y como podemos comprobar un poco más abajo. Además eliminamos la opacidad de la zona drop y quitamos el icono que habíamos añadido para indicar que el elemento draggable estaba siendo arrastrado.
Finalmente, las funciones que nos quedan se van a encargar de obtener los resultados finales de la votación cuando pulsemos sobre el botón correspondiente.

La funcion obtenerResultados, que es la que se ejecuta al pulsar dicho botón, lo primero que hace es llamar al método sanearResultados. Dado que el usuario puede variar las veces que desee el elemento a votar por diferentes opciones drop, debemos tener en cuenta que, cada vez que lo haga, se registrará la votación dentro del array resultado visto anteriormente. Por esa razón debemos obtener siempre la última votación que haya recibido cada red social, ya que, como sabemos, un array siempre va guardando la información al final del mismo, a menos que no se le indique lo contrario. Así pues podemos ver que el bucle for comienza a recorrer el array por el final y va extrayendo la primera coincidencia que encuentra según el nombre de la red social. Todo ello se guarda en un nuevo array limpio de polvo y paja, y se devuelve como resultado.
Cuando se ha recuperado ese resultado desde la función obtenerResultados donde nos encontrábamos, lo único que hacemos es presentar una ventana flotante que mostrará finalmente, ahora sí, el resultado final, recorriendo para ello el nuevo array saneado que acabamos de recuperar.

Y eso es todo.

Quiero disculparme si la explicación es algo confusa, pero la verdad es que es algo complicado intentar plasmar a fondo línea a línea, qué es lo que hace cada una, sin ser algo redundante.
Recomiendo encarecidamente descargar la aplicación, probarla y, a continuación, con el código delante, volver a leer el artículo.
La aplicación completa cuenta con todos los recursos, fuentes y estilos, que terminan por otorgarle un buen aspecto final.

Descarga desde Github

Espero que este articulo os sirva para comprender un poco mejor cómo funciona esta maravillosa utilidad de HTML5 y, sobre todo, vislumbrar las infinitas posibilidades que nos puede ofrecer.
Gracias y un saludo.-

Capturas:

 

Drag&Drop

 

Drag&Drop

 

Drag&Drop