Programando o Intentándolo

Arrastrar y soltar en HTML5 (Drag & Drop HTML5)

Esta es una de las nuevas características añadidas en HTML5, aunque ya se podía hacer drag and drop mediante otras técnicas, ahora al estar incluido en HTML5 hace que “supuestamente” funcione en todos los navegadores aunque si no cumplen los estándares como es el caso de Internet Explorer te encontraras en que en principio no funciona.

Para explicar estas nuevas funcionalidades me voy a servir de 2 ejemplos sencillos. En el primero veremos como arrastrar y soltar elementos, clonarlos o eliminarlos, y en el segundo un sencillo puzzle de 4 piezas.

Para que se pueda arrastrar y soltar un elemento hacen falta dos tipos de elementos, un elemento arrastrable (que se consigue añadiéndole al menos los atributos draggable=”true” y ondragstart=”la_funcion_que_sea(event)”) y un elemento en el que se pueda soltar a el que como mi mínimo hay que poner ondragover=”return la_funcion_que_sea(event)” y ondrop=”return la_funcion_que_sea(event)”.

Ejemplo 1 de arrastrar y soltar con HTML5: Arrastrar y soltar, clonar y eliminar elementos

En el siguiente ejemplo los elementos arrastrable1,2,3 y 4 son arrastrables y en los elementos cuadro1,2,3 y papelera se pueden soltar elementos.

Vamos a explicar brevemente para que es cada atributo del elemento arrastrable:

  • draggable: Si es true el elemento se puede arrastrar, si es false o se omite no se puede mover el elemento.
  • ondragstart: Aquí se indicara la acción que se llevara acabo cuando se empiece a arrastar el elemento.
  • ondragend: Aquí se indicara la acción que se llevara acabo cuando se termine de arrastar el elemento (cuando se suelte).

Y para el elemento al que se puedan arrastrar son estos:

  • ondragenter: Aquí se indicara la acción que se llevara acabo cuando un elemento arrastrable entre dentro del elemento.
  • ondragover: Aquí se indicara la acción que se llevara acabo cuando un elemento arrastrable este sobre el elemento. En esta función es donde se indica que elementos arrastrables se pueden soltar aquí.
  • ondragleave: Aquí se indicara la acción que se llevara acabo cuando un elemento arrastrable deje de estar encima del elemento.
  • ondrop: Aquí se indicara la acción que se llevara acabo cuando se suelte un elemento arrastrable sobre el elemento.

Una vez visto cual es el código HTML necesario para poder arrastrar y soltar elementos vamos a ver la parte de javaScript. Empezamos por las funciones del elemento arrastrable.

La primera acción que ocurre es la desencadenada dentro de ondragstart:

En esta función se define el modo en el que se va a arrastrar el elemento (none, copy, copyLink, copyMove, link, linkMove, move o all) en effecAllowed, se establece el elemento que se va a arrastrar y el modo en el que se va a guardar dicha información con setData(formato, elementó) y también se puede sustituir la imagen del elemento cuando se esta arrastrando para sustituir la que el navegador usa por defecto (el elemento con cierto grado de transparencia) por la imagen (o el elemento) indicada y las coordenadas del elemento por las que se arrastrara el elemento. De estas tres funciones solo setData es obligatoria. Además de esas funciones en la función anterior también se modifica la opacidad del elemento que se arrastra para que se vea un poco transparente y se vea mejor el elemento que se esta arrastrando.

Cuando se termina de arrastrar un elemento se elimina la información asociada al elemento dataTransfer mediante setData con el método clearData y como en al comenzar a arrastrar el elemento se cambio la opacidad del elemento se restaura a su estado original.

Ahora vamos a ver las funciones que se ejecutan cuando se producen los eventos del elemento contenedor:

Las funciones que se ejecutan en los eventos ondragenter y ondragleave se pueden usar por ejemplo para cambiar el aspecto cuando entra o sale un elemento arrastrable del elemento desde el que se llaman, en este ejemplo se pone un borde punteado gris cuando un elemento arrastrable pasa por encima y se quita el borde cuando se sale.

Cuando se coloca un elemento arrastrable sobre un elemento en el que se ‘pueda’ soltar se ejecuta el evento ondragover desde el que se llama a la siguiente función:

Lo mas importante de esta función es lo que devuelve, si se puede soltar el elemento devuelve false (si, no es un error, devuelve false si se puede soltar) y true en caso contrario.

Para indicar que elementos se pueden soltar y donde se pueden soltar en la línea 2 se obtiene el elemento que se esta arrastrando y en la 3 el id del elemento sobre el que se esta arrastrando y combinando ambos se puede conseguir que no todos los elementos se puedan soltar en todos los “contenedores”.

La siguiente función permite que se sitúe el elemento en la posición exacta en la que se suelta. Con las líneas 2 y 3 el elemento arrastrado ya estaría dentro del elemento “contenedor”, pero para que se coloque en la posición exacta que queramos hay que usar posicionamiento absoluto, por lo que tenemos que sacar las coordenadas en las que se ha soltado el elemento (líneas 14 y 15), pero si se suelta en un borde del “contendor” puede ser que parte del elemento arrastrado quede fuera del contenedor, lo que no resulta muy estético por lo que son necesarias las coordenadas del contenedor y el tamaño del contenedor y del elemento arrastrado para saber si el elemento queda fuera o dentro y si queda fuera corregir la posición para que quede dentro. (Solo esta comprobado que no se salga por la derecha y por abajo porque como en setDragImage las coordenadas eran 0,0 no se puede salir por arriba ni por la izquierda.) En la ultima línea de la función se restaura el borde al estado original que se había cambiado en la función enter.

Con arrastrar y soltar también se pueden clonar elementos de una forma muy sencilla. En la primera línea se obtiene el elemento arrastrado para poder copiarlo y en la siguiente se restaura la opacidad para que el elemento clonado tenga la opacidad original. Después se clona el elemento y se le cambia el id al elemento clonado para que sea único con un nombre y un contador que será una variable global (Una variable fuera de las funciones) para que no se repita y se añade al elemento desde el que se llama a esta función (en el caso de este ejemplo cuadro3).

Y para terminar este ejemplo, vamos con el código de la función para eliminar elementos arrastrables. Esta función es muy simple, lo único que hay que tener en cuenta es que para eliminar un elemento hay que hacerlo desde su elemento padre pero gracias al uso de parentNode solo se necesita el elemento que se quiere eliminar.

Aquí puedes ver en funcionamiento el ejemplo completo:

See the Pen Ejemplo Drag & Drop en HTML5 by Ivan Salas (@isc7) on CodePen

Ejemplo 2 de arrastrar y soltar con HTML5: Un puzzle

Este ejemplo es bastante simple y sobretodo si previamente has visto el ejemplo anterior en el que se explican los diferentes aspectos del drag&drop con HTML5.

El código es muy similar al del ejemplo anterior, el HTML es análogo aunque puesto que en esta ocasión el objetivo es hacer un puzzle hay un contenedor inicial en el que están las piezas del puzzle y otro contenedor en el que se hará el puzzle que tiene otros cuatro contendores uno para cada pieza.

Y en cuanto a las funciones javaScript tampoco hay demasiado que comentar, únicamente en la función drop la primera línea tiene que ser e.preventDefault(); para evitar que al soltar las piezas que son imágenes se produzca la acción por defecto del navegador (que se habrá la imagen) y así funcione todo como es de esperar.

Para finalizar comentar la función comprobarPuzzle que simplemente comprueba si cada pieza esta en su posición y si es así lo indica con un mensaje. Esta función hay que llamarla cada vez que se coloca una pieza por lo que se llama desde la función drop.

Y finalmente el puzzle para que lo puedas ver:

See the Pen Puzzle Drag & Drop HTML5 by Ivan Salas (@isc7) on CodePen

Aquí puedes descargar el código de los dos ejemplos.