Arrastrar y soltar es una interacción de usuario común que se puede encontrar en muchas interfaces de usuario gráficas.
Existen bibliotecas de JavaScript preexistentes para añadir la función de arrastrar y soltar a su aplicación. Sin embargo, es posible que haya situaciones en las que una biblioteca no esté disponible o que introduzca una dependencia o gasto general que su proyecto no necesita. En estas situaciones, conocer qué API están disponibles para usted en los navegadores web modernos puede ofrecer soluciones alternativas.
La API Drag and Drop HTML se basa en el modelo de evento del DOM para obtener información sobre lo que se está arrastrando o soltando y actualizar ese elemento en arrastrar o saltar. Con los controladores de eventos de JavaScript, puede convertir cualquier elemento en un elemento que se puede arrastrar o en un elemento que se puede soltar.
En este tutorial, crearemos un ejemplo de arrastrar y soltar usando la API Drag and Drop HTML con vanilla JavaScript para usar los controladores de eventos.
Para completar este tutorial, necesitará lo siguiente:
Nuestro proyecto consistirá en un contenedor con dos tipos de elementos secundarios:
Primero, abra la ventana de su terminal y cree un nuevo directorio de proyecto:
- mkdir drag-and-drop-example
Luego, diríjase a ese directorio:
- cd drag-and-drop-example
Después, cree un archivo index.html
en ese directorio:
- nano index.html
Luego, añada código reutilizable para una página web HTML:
<!DOCTYPE html>
<html>
<head>
<title>My Drag-and-Drop Example</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
</body>
</html>
Y entre las etiquetas <body>
añada su elemento draggable
y su dropzone
(objetivo para soltar):
<div class="example-parent">
<div class="example-origin">
<div
id="draggable-1"
class="example-draggable"
>
draggable
</div>
</div>
<div
class="example-dropzone"
>
dropzone
</div>
</div>
Guarde y cierre el archivo. Después, cree un archivo style.css
:
- nano style.css
Luego, añada estilos para los elementos en el archivo index.html
:
.example-parent {
border: 2px solid #DFA612;
color: black;
display: flex;
font-family: sans-serif;
font-weight: bold;
}
.example-origin {
flex-basis: 100%;
flex-grow: 1;
padding: 10px;
}
.example-draggable {
background-color: #4AAE9B;
font-weight: normal;
margin-bottom: 10px;
margin-top: 10px;
padding: 10px;
}
.example-dropzone {
background-color: #6DB65B;
flex-basis: 100%;
flex-grow: 1;
padding: 10px;
}
Esto añadirá un formato para la aplicación. Ahora puede ver index.html
en el navegador y observar que esto produce un draggable
<div>
y un dropzone
<div>
.
Luego, realizaremos explícitamente el primer <div>
arrastrable añadiendo el atributo draggable
:
<div class="example-parent">
<div class="example-origin">
<div
id="draggable-1"
class="example-draggable"
draggable="true"
>
draggable
</div>
</div>
<div
class="example-dropzone"
>
dropzone
</div>
</div>
Guarde y cierre el archivo.
Finalmente, vea index.html
en el navegador de nuevo. Si hacemos clic en el draggable
<div>
y lo arrastramos por la pantalla, debería haber una indicación visual de que se está moviendo.
El valor predeterminado para el atributo draggable
es auto
. Eso significa que el comportamiento predeterminado de su navegador determinará si el elemento se puede arrastrar. Generalmente, esto significa que las selecciones, las imágenes y los enlaces se pueden arrastrar sin especificar draggable="true".
Ahora ya tiene un archivo HTML con un elemento que se puede arrastrar. Pasaremos a añadir controladores onevent
.
Actualmente, si soltamos el ratón mientras arrastramos el elemento que se puede arrastrar, no pasará nada. Para activar una acción en arrastrar o soltar en elementos DOM, necesitaremos usar la API Drag and Drop:
ondragstart
: Este controlador de eventos se adjuntará a nuestro elemento draggable
y se accionará cuando se produzca un evento dragstart
ondragover
: Este controlador de eventos estará adjunto a nuestro elemento <^>dropzo
ne<^> y se accionará cuando se produzca un evento dra
goverondrop
: Este controlador de eventos también estará adjunto a nuestro elemento <^>dropzo
ne<^> y se accionará cuando se produzca un evento
drop.Nota: En total hay ocho controladores de eventos: o
ndrag, ondr
agend, ondrag
enter, ondra
gexit, ondrag
leave, ondra
gover, ondrag
start y o
ndrop. Para nuestro ejemplo, no los necesitaremos todos.
Primero, vamos a hacer referencia a un nuevo archivo script.js
en el archivo index.html
:
<body>
...
<script src="script.js"></script>
</body>
Luego, cree un nuevo archivo script.js
:
- nano script.js
El objeto DataTransfer
realizará un seguimiento de la información relacionada con el arrastre actual. Para actualizar nuestro elemento en arrastrar y soltar, debemos acceder directamente al objeto DataTransfer
. Para hacer esto, podemos seleccionar la propiedad dataTransfer
desde el DragEvent
del elemento DOM.
Nota: El objeto DataTransfer
puede realizar un seguimiento técnico de la información de varios elementos que se arrastran al mismo tiempo. Por nuestro ejemplo, nos enfocaremos en arrastrar un elemento.
El método setData
del objeto dataTransfer
se puede usar para configurar la información del estado de arrastre para el elemento que arrastra actualmente. Emplea dos parámetros:
Nuestro objetivo es mover nuestro elemento draggable
a un nuevo elemento principal. Deberíamos poder seleccionar nuestro elemento draggable
con un id
único. Podemos configurar el id
del elemento arrastrado con el método setData
para que pueda utilizarse más adelante.
Revisemos nuestro archivo script.js
y creemos una nueva función para usar setData
:
function onDragStart(event) {
event
.dataTransfer
.setData('text/plain', event.target.id);
}
Nota: Los navegadores Internet Explorer del 9 al 11 aparentemente tienen problemas para usar 'text/plain'
. El formato debe 'text'
para ese navegador.
Para actualizar el estilo CSS del elemento arrastrado, podemos acceder a sus estilos usando el evento DOM de nuevo y configurando el estilo que nuestra preferencia para el currentTarget
.
Agreguemos a nuestra función y cambiemos el backgroundColor
a yellow
:
function onDragStart(event) {
event
.dataTransfer
.setData('text/plain', event.target.id);
event
.currentTarget
.style
.backgroundColor = 'yellow';
}
Nota: Los estilos que cambie deberán actualizarse manualmente de nuevo al soltar si desea estilos de arrastrar solamente. Si cambia algo cuando empieza a arrastrar, el elemento arrastrado mantendrá ese nuevo estilo a menos que lo modifique de nuevo.
Ahora ya tenemos nuestra función de JavaScript para cuando se inicia el arrastre.
Podemos añadir ondragstart
al elemento draggable
en index.html
:
<div class="example-parent">
<div class="example-origin">
<div
id="draggable-1"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
draggable
</div>
</div>
<div class="example-dropzone">
dropzone
</div>
</div>
Vea index.html
en su navegador. Si intenta arrastrar su elemento ahora, se aplicará el estilo declarado en nuestra función:
Sin embargo, no pasará nada cuando suelte el botón del ratón.
El siguiente controlador de eventos que se accionó en esta secuencia es ondra
gover.
Normalmente, el comportamiento predeterminado de soltar para ciertos elementos DOM como <div>
en navegadores no acepta la función de soltar. Este comportamiento interceptará el comportamiento que estamos tratando de implementar. Para garantizar que obtengamos el comportamiento de soltar deseado, aplicaremos preventDefault
.
Revisemos el archivo script.js
y creemos una nueva función para usar preventDefault
: Añada este código al final del archivo:
function onDragOver(event) {
event.preventDefault();
}
Ahora, podemos añadir ondragover
a nuestro elemento dropzone
en index.html
:
<div class="example-parent">
<div class="example-origin">
<div
id="draggable-1"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
draggable
</div>
</div>
<div
class="example-dropzone"
ondragover="onDragOver(event);"
>
dropzone
</div>
</div>
En este momento, aún no hemos escrito el código para controlar la función real de soltar. El controlador de eventos final que se accionó en esta secuencia es ondrop
.
Volvamos a revisar nuestro archivo script.js
y creemos una nueva función.
Podemos hacer referencia a los datos que guardamos anteriormente con el método setData
del objeto dataTransfer
. Usaremos el método getData
del objeto dataTransfer
. Los datos que configuramos fueron el id
, así que eso es lo que se devolverá:
function onDrop(event) {
const id = event
.dataTransfer
.getData('text');
}
Seleccione nuestro elemento draggable
con el id
que recuperamos:
function onDrop(event) {
// ...
const draggableElement = document.getElementById(id);
}
Seleccione nuestro elemento dropzone
:
function onDrop(event) {
// ...
const dropzone = event.target;
}
Añada nuestro elemento draggable
al dropzone
:
function onDrop(event) {
// ...
dropzone.appendChild(draggableElement);
}
Restablezca nuestro objeto dataTransfer
:
function onDrop(event) {
// ...
event
.dataTransfer
.clearData();
}
Ahora, podemos añadir ondragover
a nuestro elemento dropzone
en index.html
:
<div class="example-parent">
<div class="example-origin">
<div
id="draggable-1"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
draggable
</div>
</div>
<div
class="example-dropzone"
ondragover="onDragOver(event);"
ondrop="onDrop(event);"
>
dropzone
</div>
</div>
Una vez hecho esto, tendremos una función de arrastrar y soltar finalizada. Vea index.html
en su navegador y arrastre el elemento draggable
al dropzone
.
Nuestro ejemplo gestiona el caso de un solo elemento que se puede arrastrar y un único objetivo para soltar. Puede tener varios elementos que se pueden arrastrar, varios objetivos para soltar y personalizarlos con todos los demás controladores de eventos de la API Drag and Drop
Aquí hay un ejemplo más de cómo se podría usar esta API: una lista de cosas por hacer con tareas que se pueden arrastrar de una columna "Tareas pendientes"
a otra columna de "Completadas"
.
Para crear su propia lista de tareas pendientes, añada más elementos que se pueden arrastrar con id
únicos a index.html
:
<div class="example-parent">
<h1>To-do list</h1>
<div class="example-origin">
To-do
<div
id="draggable-1"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
thing 1
</div>
<div
id="draggable-2"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
thing 2
</div>
<div
id="draggable-3"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
thing 3
</div>
<div
id="draggable-4"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
thing 4
</div>
</div>
<div
class="example-dropzone"
ondragover="onDragOver(event);"
ondrop="onDrop(event);"
>
Done
</div>
</div>
Vea index.html
en su navegador y arrastre los elementos en la columna Tareas pendientes a la columna Completadas. Ha creado una aplicación de tareas pendientes y ha probado su funcionalidad.
En este artículo, creó una app de tareas pendientes para explorar la funcionalidad de arrastrar y soltar que está disponible para los navegadores web modernos.
La API Drag and Drop proporciona múltiples opciones para personalizar sus acciones más allá de arrastrar y soltar. Por ejemplo, puede actualizar el estilo CSS de sus elementos arrastrados. Además, en vez de mover el elemento, puede elegir copiar el elemento que se puede arrastrar de forma que se duplique al soltarse
Tenga en cuenta que, si bien muchos navegadores web son compatibles con esta tecnología, es posible que no pueda serle útil si su audiencia tiene dispositivos que no son compatibles con esta funcionalidad.
Para obtener más información sobre todo lo que puede soltar con la API Drag and Drop , consulte los documentos de MDN.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!