Micaela 23 de agosto de 2009 a las 09.05
   Imprimir artículo
elWebmaster.com

Drag and Drop con HTML5, paso a paso


html5-draganddropDrag and Drop (“Arrastrar y soltar”) es una de las m谩s fundamentales interacciones logradas por las interfaces gr谩ficas de usuario. Siempre se consider贸 ideal que los navegadores ofrecieran soporte para esta funcionalidad.

Este deseo fue cumplido actualmente por las especificaciones que HTML 5 y Firefox 3.5 poseen acerca de eventos drag and drop. En esta nota contamos c煤ales son y en qu茅 consisten.

Sin m谩s rodeos, aqu铆 est谩n los nuevos eventos drag and drop:

dragstart

Un arrastrado ha sido iniciado, con el elemento arrastrado como el objetivo del evento.

drag

El mouse ha sido movido, con el elemento arrastrado como el objetivo del evento.

dragenter

El elemento arrastrado ha sido movido dentro de un receptor de soltado, con el elemento receptor del soltado como el objetivo del evento.

dragover

El elemento arrastrado ha sido movido sobre un receptor de soltado, con el elemento receptor del soltado como el objetivo del evento. Dado que el comportamiento por defecto es cancelar soltados, devolver false o llamar a preventDefault() en el manejador de eventos indica que un soltado es permitido aqu铆.

dragleave

El elemento arrastrado ha sido movido fuera de un receptor de soltado, con el elemento receptor del soltado como el objetivo del evento.

drop

El elemento arrastrado ha sido volcado de forma exitosa en un receptor de soltado, con el elemento receptor del soltado como el objetivo del evento.

dragend

Un arrastrado ha sido finalizado, de forma exitosa o no, con el elemento arrastrado como el objetivo del evento.

Como los eventos de mouse de anta帽o, los receptores pueden ser adjuntados directamente a los elementos usando addEventListener() o por medio de tu librer铆a JS favorita.

Consideren el siguiente ejemplo utilizando jQuery:

<div id=”newschool”>

<div class=”dragme”>Drag me!</div>

<div class=”drophere”>Drop here!</div>

</div>

<script type=”text/javascript”>

$(document).ready(function() { $(‘#newschool .dragme’)

.attr(‘draggable’, ‘true’)

.bind(‘dragstart’, function(ev) {

var dt = ev.originalEvent.dataTransfer;

dt.setData(“Text”, “Dropped in zone!”);

return true; })

.bind(‘dragend’, function(ev) { return false; });

$(‘#newschool .drophere’)

.bind(‘dragenter’, function(ev) { $(ev.target).addClass(‘dragover’);

return false; })

.bind(‘dragleave’, function(ev) {

$(ev.target).removeClass(‘dragover’);

return false; })

.bind(‘dragover’, function(ev) {

return false; })

.bind(‘drop’, function(ev) {

var dt = ev.originalEvent.dataTransfer; alert(dt.getData(‘Text’));

return false; }); });

</script>

Gracias a los nuevos eventos y jQuery, este ejemplo es tanto corto como simple, pero contiene una gran cantidad de funcionalidades.

Antes de seguir, existen por lo menos tres cosas del c贸digo anterior que vale la pena mencionar:

Los objetivos de soltado (drop) est谩n permitidos por virtud de tener receptores para eventos de soltado. Pero, por las especificaciones HTML 5, los elementos arrastrables necesitan un atributo de draggable=”true”, programado ya sea en el c贸digo o en JavaScript, de esta manera:

$(‘#newschool聽.dragme’).attr(‘draggable’, ‘true’)

El evento DOM original (en oposici贸n al envoltorio de evento jQuery) ofrece una propiedad llamada dataTransfer. M谩s all谩 de la simple manipulaci贸n de elementos, el nuevo evento drag and drop acomoda la transmisi贸n de informaci贸n definida por el usuario durante el curso de la interacci贸n.

Miren este demo, y el c贸digo Javascript asociado para ver m谩s acerca de estos eventos y delegaci贸n de eventos.

Usando dataTransfer

Como mencionamos en la secci贸n anterior, los nuevos eventos drag and drop nos permiten enviar informaci贸n junto con el elemento arrastrado. Pero es todav铆a mejor: Tus objetivos de soltado pueden recibir informaci贸n transferida por objetos de contenido arrastrados en la ventana desde otras ventanas de navegador, e incluso otras aplicaciones.

Miren el demo y el c贸digo asociado para obtener una idea de todo lo que es possible con dataTransfer.

Resumiendo, las estrellas de este show son los m茅todos setData() y getData() de la propiedad dataTransfer expuesta por el objeto evento.

El m茅todo setData() es llamado tipicamente en el receptor dragstart, cargando dataTransfer con una o m谩s cadenas de contenido con tipos de contenido recomendado asociado.

Aqu铆 hay un r谩pido snippet del c贸digo de ejemplo:

var dt = ev.originalEvent.dataTransfer;

dt.setData(‘text/plain’, $(‘#logo’).parent().text());

dt.setData(‘text/html’, $(‘#logo’).parent().html());

dt.setData(‘text/uri-list’, $(‘#logo’)[0].src);

Por otra parte, getData() te permite consultar por tipo (ej: text/html seguido por text/plain). Esto, a la vez, te permite decidir sobre los tipos de contenido aceptables a la hora del evento de soltado e incluso durante dragover para ofrecer un feedback de los tipos que no son aceptables durante el arrastre.

Aqu铆 hay otro ejemplo del c贸digo:

var dt = ev.originalEvent.dataTransfer;

$(‘.content_url .content’).text(dt.getData(‘text/uri-list’));

$(‘.content_text .content’).text(dt.getData(‘text/plain’));

$(‘.content_html .content’).html(dt.getData(‘text/html’));

En lo que dataTransfer realmente se destaca, es que te permite volcar objetivos para recibir contenido de fuentes exteriores a tus elementos arrastrables definidos e incluso desde afuera del navegador.Firefox acepta tales arrastres, e intenta poblar dataTransfer con tipos de contenido apropiado extra铆dos del objeto externo.

As铆, podr铆as seleccionar alg煤n texto en un procesador de textos y volcarlo en uno de tus elementos, y por lo menos esperar encontrarlo disponible como contenido text/plain.

Incluso puedes seleccionar contenido en la ventana de otro navegador, y esperar ver text/html aparecer en tus eventos. Mira este demo para ver qu茅 sucede cuando tratas de arrastrar varios elementos (ej. Im谩genes, tablas, y listas) y resaltar contenido de otras ventanas dentro de los 铆tems que est谩n ah铆.

Utilizando im谩genes Feedback Drag

Un aspecto importante de la interacci贸n drag and drop es la representaci贸n del objeto que est谩 siendo arrastrado. Por defecto en Firefox, esto es una imagen “fantasma” del propio elemento arrastrado. Pero la propiedad dataTransfer del objeto de evento original expone el m茅todo setDragImage() para utilizar en personalizaci贸n esta representaci贸n.

Pueden ver el demo de esto, como as铆 tambi茅n el c贸digo JS asociado. La esencia se puede ver delimitada en estos snippets de c贸digo:

var dt = ev.originalEvent.dataTransfer;

dt.setDragImage( $(‘#feedback_image h2′)[0], 0, 0);

dt.setDragImage( $(‘#logo’)[0], 32, 32);

var canvas = document.createElement(“canvas”);

canvas.width = canvas.height = 50;

var ctx = canvas.getContext(“2d”);

ctx.lineWidth = 8; ctx.moveTo(25,0);

ctx.lineTo(50, 50); ctx.lineTo(0, 50);

ctx.lineTo(25, 0); ctx.stroke();

dt.setDragImage(canvas, 25, 25);

Puedes proveer un nodo DOM como primer par谩metro a setDragImage(), el cual incluye todo, desde texto hasta im谩genes e incluso elementos canvas. Los segundos dos par谩metros indican lo que deber铆a aparecer a la izquierda y en la parte superior mientras se arrastra.

Por ejemplo, dado que la imagen #logo es de 64脳64, los par谩metros en el segundo m茅todo setDragImage() colocan el mouse justo en el medio de la imagen. Por otro lado, la primera llamada posiciona la imagen de feedback de tal forma que el mouse descansa en la esquina superior izquierda.

Utilizando efectos Drop

Como mencionamos al comienzo del art铆culo, la interacci贸n drag and drop ha sido utilizada para soportar acciones tales como copiado, movimiento y enlazado. De acuerdo a esto, la especificaci贸n HTML 5 acomoda estas operaciones en la forma de las propiedades effectAllowed y dropEffect expuestas por el objeto Event.

Para una vista r谩pida miren el demo de esta propiedad, como as铆 tambi茅n el c贸digo Javascript asociado.

La idea b谩sica es que el evento receptor dragstart puede programar un valor para effectAllowed como 茅ste:

var dt = ev.originalEvent.dataTransfer;

switch (ev.target.id) { case ‘effectdrag0′: dt.effectAllowed = ‘copy';

break; case ‘effectdrag1′: dt.effectAllowed = ‘move';

break; case ‘effectdrag2′: dt.effectAllowed = ‘link'; break; case ‘effectdrag3′: dt.effectAllowed = ‘all'; break;

case ‘effectdrag4′: dt.effectAllowed = ‘none'; break; }

Las elecciones disponibles para esta propiedad incluyen:

  • none: No se permite ninguna operaci贸n.
  • copy: S贸lo copia.
  • move: S贸lo mover.
  • link: S贸lo link.
  • copyMove: S贸lo copiar o mover.
  • copyLink: S贸lo link o copiar.
  • linkMove: S贸lo mover o link.
  • all: Copiar, mover, o link

Por otra parte, el evento dragover puede programar el valor de la propiedad dropEffect para indicar el efecto esperado invocado en un soltado exitoso. Si el valor no coincide con effectAllowed, el soltado ser谩 considerado como cancelado en la consulta.

En el demo, podr谩n ver que s贸lo los elementos con efectos que coinciden pueden ser soltados en las zonas de soltado apropiadas. Esto se logra con c贸digo como el siguiente:

var dt = ev.originalEvent.dataTransfer;

switch (ev.target.id) { case ‘effectdrop0′: dt.dropEffect = ‘copy';

break;

case ‘effectdrop1′: dt.dropEffect = ‘move'; break;

case ‘effectdrop2′: dt.dropEffect = ‘link'; break;

case ‘effectdrop3′: dt.dropEffect = ‘all'; break;

case ‘effectdrop4′: dt.dropEffect = ‘none'; break;

A pesar de que el sistema operativo puede proveer algo de feedback, tambi茅n puedes utilizar estas propiedades para actualizar tu propio feedback visible, ambos en el elemento arrastrado y en la zona de soltado propiamente dicha.

Conclusi贸n

En HTML5 y Firefox lograron soportar esta forma de interacci贸n de usuario, logrando que sea sencilla y a su vez concisa y poderosa en el navegador. Pero m谩s all谩 de la nueva simplicidad de estos eventos, la posibilidad de transferir contenido entre aplicaciones abre un nuevo conjunto de posibilidades para las aplicaciones basadas en la web y la colaboraci贸n con software de escritorio en general.

Fuente: OxDECAFBAD


Enviar a Del.icio.us Enviar a Meneame Enviar a Digg Enviar a Fresqui Enviar a Enchilame

Deja tu opinión

© 2007 - 2008 elWebmaster.com | Powered by Wordpress | Diseño CSS y XHTML válido. | Algunos íconos basados en FamFamFam Mini
Acceder