Tutorial

Cómo crear elementos de arrastrar y soltar con Vanilla JavaScript y HTML

Published on November 17, 2020
authorauthor

Jess Mitchell and Bradley Kouchi

Español
Cómo crear elementos de arrastrar y soltar con Vanilla JavaScript y HTML

Introducción

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.

Requisitos previos

Para completar este tutorial, necesitará lo siguiente:

  • Un navegador web moderno compatible con la API Drag and Drop (Chrome 4+, Firefox 3.5+, Safari 3.1+, Edge 18+).

Paso 1: Crear el proyecto y marcado inicial

Nuestro proyecto consistirá en un contenedor con dos tipos de elementos secundarios:

  • Elementos secundarios que puede arrastrar
  • Elementos secundarios en los que se pueden soltar elementos

Primero, abra la ventana de su terminal y cree un nuevo directorio de proyecto:

  1. mkdir drag-and-drop-example

Luego, diríjase a ese directorio:

  1. cd drag-and-drop-example

Después, cree un archivo index.html en ese directorio:

  1. nano index.html

Luego, añada código reutilizable para una página web HTML:

index.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):

index.html
<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:

  1. nano style.css

Luego, añada estilos para los elementos en el archivo index.html:

style.css
.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>.

Captura de pantalla de los divs draggable y dropzone

Luego, realizaremos explícitamente el primer <div> arrastrable añadiendo el atributo draggable:

index.html
<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.

Paso 2: Gestionar eventos de arrastrar y soltar con JavaScript

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 <^>dropzone<^> y se accionará cuando se produzca un evento dragover
  • ondrop: Este controlador de eventos también estará adjunto a nuestro elemento <^>dropzone<^> y se accionará cuando se produzca un evento drop.

Nota: En total hay ocho controladores de eventos: ondrag, ondragend, ondragenter, ondragexit, ondragleave, ondragover, ondragstart y ondrop. Para nuestro ejemplo, no los necesitaremos todos.

Primero, vamos a hacer referencia a un nuevo archivo script.js en el archivo index.html:

index.html
<body>
  ...
  <script src="script.js"></script>
</body>

Luego, cree un nuevo archivo script.js:

  1. 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:

  • una cadena que declara el formato del segundo parámetro
  • los datos reales que se hayan transferido

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:

script.js
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:

script.js
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:

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:

Gif animado que representa un elemento que se arrastra, pero que no se suelta

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 ondragover.

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:

script.js
function onDragOver(event) {
  event.preventDefault();
}

Ahora, podemos añadir ondragover a nuestro elemento dropzone en index.html:

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á:

script.js
function onDrop(event) {
  const id = event
    .dataTransfer
    .getData('text');
}

Seleccione nuestro elemento draggable con el id que recuperamos:

script.js
function onDrop(event) {
  // ...

  const draggableElement = document.getElementById(id);
}

Seleccione nuestro elemento dropzone:

script.js
function onDrop(event) {
  // ...

  const dropzone = event.target;
}

Añada nuestro elemento draggable al dropzone:

script.js
function onDrop(event) {
  // ...

  dropzone.appendChild(draggableElement);
}

Restablezca nuestro objeto dataTransfer:

script.js
function onDrop(event) {
  // ...

  event
    .dataTransfer
    .clearData();
}

Ahora, podemos añadir ondragover a nuestro elemento dropzone en index.html:

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.

Gif animado que representa un elemento que se arrastra y se suelta en un objetivo para soltar

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

Paso 3: Crear un ejemplo avanzado con múltiples elementos que se pueden arrastrar

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".

Gif animado que representa múltiples tareas siendo arrastradas y soltadas en la columna Completadas

Para crear su propia lista de tareas pendientes, añada más elementos que se pueden arrastrar con id únicos a index.html:

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.

Conclusión

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.

Learn more about our products

About the authors
Default avatar
Jess Mitchell

author



Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


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!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.