Drag 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








Comentarios recientes
- Prof.Yeow: gracias! util y corriendo en mi paginas http://yeow.com.ar ;-)...
- alan: se puede o no se puede usar alcohol...
- ESCRONO: HOLA AL MOMENTO DE HACER REDIMENSION EN LA PANTALLA NO SE LLENA POR COMP...
- Wiz: 1 palabra que describe su aporte, EXCELENTE!!!
Muchas gracias por est...
- Ofertas: muchas Gracias...
- Jesus: Para Succubus Evaligan, deberias probar Firefox 4 Beta 3, esta buenisimo...
Feed de los comentarios