Una de las muchas ventajas de HTML5 es que viene con la posibilidad de incorporar un Drag and Drop de manera relativamente sencilla, sin necesidad de usar librerías externas. Lo único necesario es saber un poco de eventos de JavaScript.
Antes de continuar os aviso de que en ciertos navegadores funciona de una manera diferente. Por ejemplo, en firefox no podremos arrastrar el objeto hasta asignarle el objeto dataTransfer y en Chrome se puede arrastrar desde el principio.
Para el ejemplo usaré 2 div con los id de origen y destino. Ambos tendrán un estilo para poder diferenciarlos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#origen { background-color: #FFC300 ; width:100px; height:100px; cursor:move; } #destino { background-color:#C70039; width:200px; height:200px; padding:5px; margin-bottom:5px; } |
Lo siguiente será añadir el atributo draggable al elemento que vamos arrastrar.
1 2 |
<div id="origen" draggable="true"></div> <div id="destino"></div> |
Ahora será necesario emplear la magia de JavaScript. Antes del cierre del body, añade una etiqueta script con el siguiente código
1 2 3 4 5 6 7 8 |
<script> var origen = document.getElementById("origen"); origen.addEventListener("dragstart", function(evt) { this.style.border = "2px solid red"; this.style.opacity = "0.5"; }, false); </script> |
Básicamente ese código indica que elemento origen al seleccionar y arrastrar, se le añade un borde rojo y se vuelve transparente. En este caso he empleado una función anónima pero puedes usar una función ya declarada.
Dentro de la misma etiqueta, vamos añadir como reaccionará el elemento destino con ciertos eventos
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var destino = document.getElementById("destino"); destino.addEventListener("dragenter", function(evt) { this.style.backgroundColor = "#DAF7A6"; // Se cambia el colro de fondo }, false); destino.addEventListener("dragleave", function(evt) { this.style.backgroundColor = "#C70039"; //Se deja el color original }, false); destino.addEventListener("dragover", function(evt) { if (evt.preventDefault) evt.preventDefault(); return false; }, false); |
En este caso se manejan 3 eventos:
- Dragenter – Cuando metamos, no soltar, el elemento origen en el div destino este cambiará de color
- Dragleave – En caso de apartar el elemento origen del destino este volvería a su color original.
- Dragover – Se refiere cuando el elemento origen pasa por encima del destino. Al ser un evento que se dispara constantemente se devuelve un false para que no haga nada. Si quieres comprobar el efecto, borra ese código y pon un alert(), verás que se muestra múltiples veces al pasar el elemento origen por destino.
Objeto dataTransfer
Finalmente, necesitamos enlazar el objeto dataTransfer con los elementos que el navegador necesita para manejar las acciones de Drag and Drop. Para ello es necesario modificar el código que usamos en el dragStart
1 2 3 4 5 6 7 |
origen.addEventListener("dragstart", function(evt) { this.style.border = "2px solid red"; this.style.opacity = "0.5"; evt.dataTransfer.effectAllowed = "move"; evt.dataTransfer.setData("ID", this.id); }, false); |
El atributo effectAllowed indica que feedback visual o lo que veremos cuando comencemos a arrastrar, que sería mover el elemento. Por otro lado, el atributo setData permite indicar que datos pasará el elemento que se este arrastrando cuando lo soltemos en el destino, que en este caso el parámetro ID tendrá como valor el id del elemento que estemos arrastrando.
También habrá que usar el objeto dataTransfer cuando se realice el drop o suelte el elemento. Agrega el siguiente código
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
destino.addEventListener("drop", function(evt) { if (evt.preventDefault) evt.preventDefault(); if (evt.stopPropagation) evt.stopPropagation(); this.style.backgroundColor = "#C70039"; //Se deja el color original var id = evt.dataTransfer.getData("ID"); // Obtenemos el ID var elem = document.getElementById(id); elem.parentNode.removeChild(elem); // Se elimina el elemento que estamos arrastrando this.appendChild(elem); // Se añade en el destino //Al elemento origen le quito el borde y le pongo la opacidad normal elem.style.border = ""; // black dotted-line border elem.style.opacity = "1"; // black dotted-line border return false; }, false); |
Al soltar el objeto, lo eliminamos y los añadimos dentro del elemento destino gracias al getData el cuál obtenemos el id del elemento y podemos manipularlo.
Ahora cuando arrastremos el origen al destino debería de quedar de la siguiente forma
Resultado final del drag and drop
Y hasta aquí drag and drop con HTML5, estoy seguro que le encontraréis un buen uso. A seguir picando 🙂