Saltar al contenido

JavaScript Drag and Drop: Simplificado con ejemplo interactivo

En este tutorial, exploraremos la funcionalidad de arrastrar y soltar en JavaScript, una característica poderosa que mejora la interactividad en las páginas web. Comenzaremos discutiendo los conceptos y algoritmos fundamentales que hacen posible el arrastrar y soltar, luego pasaremos a un ejemplo práctico donde podrás ver estas ideas en acción. Este ejemplo implica un icono de luz que puedes arrastrar a un área oscura para iluminarla.

¿Qué es el arrastrar y soltar?

El arrastrar y soltar es una interacción de la interfaz de usuario que permite a los usuarios tomar un objeto y moverlo a una ubicación diferente en la pantalla. Esta interacción es común en la gestión de archivos en tu computadora, al organizar elementos en juegos o en herramientas de edición en línea.

Conceptos fundamentales del arrastrar y soltar en JavaScript

El algoritmo de arrastrar y soltar

  1. Iniciar el arrastre:
    • El proceso comienza cuando el usuario hace clic en el elemento y mantiene presionado el botón del ratón.
  2. Arrastrar el elemento:
    • A medida que se mueve el ratón, el elemento sigue la trayectoria del cursor por la pantalla.
  3. Soltar el elemento:
    • El elemento se suelta cuando el usuario suelta el botón del ratón, colocándolo en una nueva posición.

Comprender las zonas de destino (droppables)

Las zonas de destino (droppables) son áreas designadas para recibir los elementos arrastrables. Estas áreas detectan cuándo un objeto arrastrable está sobre ellas y pueden desencadenar acciones específicas como respuesta.

INFO

Asegúrate de que tu funcionalidad de arrastrar y soltar sea compatible con pantallas táctiles. Los usuarios móviles deberían poder arrastrar y soltar con gestos táctiles. Considera implementar eventos táctiles (touchstart, touchmove, touchend) o utilizar una biblioteca ligera para la compatibilidad entre dispositivos.

Ejemplo interactivo: Área de luz y oscuridad

Pongamos la teoría en práctica con un ejemplo simple pero interactivo. Utilizaremos un icono de bombilla como nuestro objeto arrastrable. Cuando este icono se mueve sobre un área oscura, el área se iluminará, simulando el efecto de encender una luz.

Configuración del HTML y CSS

Primero, definimos la estructura y el estilo básicos. Incluimos una caja oscura y un icono de bombilla.

Estructura HTML


html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Interactive Lighting with Drag and Drop</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" />
<style>
  #darkArea {
    width: 300px;
    height: 300px;
    background-color: #333;
    position: relative;
    margin-top: 20px;
  }
  #lightIcon {
    font-size: 48px;
    color: #ccc;
    cursor: pointer;
    position: absolute;
  }
</style>
</head>
<body>
<div id="main">
  <div id="darkArea"></div>
  <i id="lightIcon" class="fas fa-lightbulb"></i>
</div>

<script>
// JavaScript will be added here.
</script>
</body>
</html>

Implementación de JavaScript

Ahora, agreguemos funcionalidad para hacer que la bombilla sea arrastrable y reactiva al área oscura.

Explicación del código JavaScript


javascript
<script>
  // Get references to the light bulb icon and the dark area on the webpage
  var lightIcon = document.getElementById("lightIcon");
  var darkArea = document.getElementById("darkArea");

  // Variables to track whether the dragging is active and to store position data
  var active = false;
  var initialX, initialY, currentX, currentY, xOffset = 0, yOffset = 0;

  // Listen for the mouse down event on the light bulb icon
  lightIcon.addEventListener("mousedown", function(e) {
    // Record the starting position of the mouse and adjust by any existing offset
    initialX = e.clientX - xOffset;
    initialY = e.clientY - yOffset;
    // Set the active flag to true, indicating that dragging has started
    active = true;
  });

  // Listen for mouse movement across the entire document
  document.addEventListener("mousemove", function(e) {
    // If not dragging, don't do anything
    if (!active) return;
    // Calculate the new position of the mouse
    currentX = e.clientX - initialX;
    currentY = e.clientY - initialY;
    // Update the offset with the new position
    xOffset = currentX;
    yOffset = currentY;
    // Move the light bulb icon to the new position
    lightIcon.style.transform = "translate3d(" + currentX + "px, " + currentY + "px, 0)";
  });

  // Listen for the mouse up event across the entire document
  document.addEventListener("mouseup", function() {
    // Save the final position of the light bulb
    initialX = currentX;
    initialY = currentY;
    // Set the active flag to false, indicating dragging has ended
    active = false;
    // Check if the light bulb is inside the dark area
    if (isInside(darkArea, lightIcon)) {
      // Change the background color of the dark area to yellow
      darkArea.style.backgroundColor = "yellow";
      // Change the color of the light bulb to yellow
      lightIcon.style.color = "yellow";
    } else {
      // Revert the dark area's color to dark
      darkArea.style.backgroundColor = "#333";
      // Revert the light bulb's color to gray
      lightIcon.style.color = "#ccc";
    }
  });

  // Function to check if the light bulb is inside the dark area
  function isInside(container, element) {
    // Get the position of the container and the element
    var containerRect = container.getBoundingClientRect();
    var elementRect = element.getBoundingClientRect();
    // Return true if the element is within the container's boundaries
    return (
      elementRect.left >= containerRect.left &&
      elementRect.right <= containerRect.right &&
      elementRect.top >= containerRect.top &&
      elementRect.bottom <= containerRect.bottom
    );
  }
</script>

Este script hace que un icono de bombilla en tu pantalla sea movible con el ratón. Puedes hacer clic en la bombilla, arrastrarla y ver cómo interactúa con un área oscura en la pantalla. Así es lo que hace cada parte del script en términos simples:

  1. Preparar todo: Primero, el script identifica el icono de la bombilla y el área oscura en tu página web. También establece algunas reglas para rastrear el movimiento del ratón.

  2. Comenzar a arrastrar:

    • Cuando presionas la bombilla con el ratón, el script recuerda dónde comenzaste. Esto le ayuda a saber cuánto mueves la bombilla más tarde.
  3. Mover la bombilla:

    • A medida que mueves el ratón mientras mantienes presionado el botón, el script hace que la bombilla siga tu ratón. Lo hace actualizando constantemente la posición de la bombilla para que coincida con la ubicación de tu ratón.
  4. Soltar la bombilla:

    • Cuando sueltas el botón del ratón, el script verifica si la bombilla está sobre el área oscura. Si lo está, el área oscura se iluminará, volviéndose amarilla, y la bombilla también cambia de color para indicar que está encendida. Si no está sobre el área oscura, todo vuelve a la normalidad.
  5. Verificar la posición:

    • Existe un conjunto especial de reglas (una función llamada isInside) que ayuda al script a saber si la bombilla está sobre el área oscura o no. Compara la posición de la bombilla con los límites del área oscura.

INFO

Usa translate3d en tus transformaciones CSS para arrastrar elementos. Aprovecha la aceleración por GPU, lo que conduce a movimientos más suaves y menor carga de CPU, lo cual es crucial para aplicaciones intensivas en rendimiento.

Ejemplo completo

Ahora, es hora de ver todo en acción, así que:


html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Interactive Lighting with Drag and Drop</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" />
    <style>
      #darkArea {
        width: 300px;
        height: 300px;
        background-color: #333;
        position: relative;
        margin-top: 20px;
      }
      #lightIcon {
        font-size: 48px;
        color: #ccc;
        cursor: pointer;
        position: absolute;
      }
    </style>
  </head>
  <body>
    <div id="main">
     <p>Move the light into the dark area to light it up!</p>
      <div id="darkArea"></div>
      <i id="lightIcon" class="fas fa-lightbulb"></i>
    </div>

    <script>
      // Get references to the light bulb icon and the dark area on the webpage
      var lightIcon = document.getElementById("lightIcon");
      var darkArea = document.getElementById("darkArea");

      // Variables to track whether the dragging is active and to store position data
      var active = false;
      var initialX,
        initialY,
        currentX,
        currentY,
        xOffset = 0,
        yOffset = 0;

      // Listen for the mouse down event on the light bulb icon
      lightIcon.addEventListener("mousedown", function (e) {
        // Record the starting position of the mouse and adjust by any existing offset
        initialX = e.clientX - xOffset;
        initialY = e.clientY - yOffset;
        // Set the active flag to true, indicating that dragging has started
        active = true;
      });

      // Listen for mouse movement across the entire document
      document.addEventListener("mousemove", function (e) {
        // If not dragging, don't do anything
        if (!active) return;
        // Calculate the new position of the mouse
        currentX = e.clientX - initialX;
        currentY = e.clientY - initialY;
        // Update the offset with the new position
        xOffset = currentX;
        yOffset = currentY;
        // Move the light bulb icon to the new position
        lightIcon.style.transform = "translate3d(" + currentX + "px, " + currentY + "px, 0)";
      });

      // Listen for the mouse up event across the entire document
      document.addEventListener("mouseup", function () {
        // Save the final position of the light bulb
        initialX = currentX;
        initialY = currentY;
        // Set the active flag to false, indicating dragging has ended
        active = false;
        // Check if the light bulb is inside the dark area
        if (isInside(darkArea, lightIcon)) {
          // Change the background color of the dark area to yellow
          darkArea.style.backgroundColor = "yellow";
          lightIcon.style.color = "yellow";
        } else {
          // Revert the dark area's color to dark
          darkArea.style.backgroundColor = "#333";
          // Revert the light bulb's color to gray
          lightIcon.style.color = "#ccc";
        }
      });

      // Function to check if the light bulb is inside the dark area
      function isInside(container, element) {
        // Get the position of the container and the element
        var containerRect = container.getBoundingClientRect();
        var elementRect = element.getBoundingClientRect();
        // Return true if the element is within the container's boundaries
        return elementRect.left >= containerRect.left && elementRect.right <= containerRect.right && elementRect.top >= containerRect.top && elementRect.bottom <= containerRect.bottom;
      }
    </script>
  </body>
</html>

Eventos principales del ratón utilizados:

  1. mousedown: Este evento se activa cuando el usuario presiona el botón del ratón sobre el icono de la bombilla. Marca el inicio del arrastre y registra la posición inicial del cursor.
  2. mousemove: Este evento se dispara cuando se mueve el ratón. Si el arrastre está activo (es decir, el botón del ratón sigue presionado), calcula la nueva posición del icono en función del movimiento del cursor y actualiza la posición de la bombilla en la pantalla.
  3. mouseup: Este evento ocurre cuando el usuario suelta el botón del ratón, marcando el final del arrastre. Verifica si la bombilla está dentro de los límites del área oscura para decidir si cambiar el color de fondo del área.

Como aprendimos en el artículo Eventos del ratón, estos eventos son fundamentales para crear funcionalidad interactiva de arrastrar y soltar, permitiendo que los elementos de una página web se muevan dinámicamente e interactúen mediante el uso de un ratón.

Conclusión

Las acciones de arrastrar y soltar pueden hacer que tus sitios web sean más fáciles de usar y se vean mejor. Al aprender los conceptos básicos y probarlos con ejemplos reales, puedes aprovechar estas emocionantes características. Esto hace que tus sitios web sean más divertidos e interactivos.

Práctica

¿Cuáles son las afirmaciones verdaderas sobre la funcionalidad de arrastrar y soltar en JavaScript?

¿Te resulta útil?

Vista previa dual-run — compárala con las rutas Symfony en producción.