El Atributo ONDRAGEND

Es parte de la API de Drag and Drop de HTML5 y se activa cuando el usuario finaliza una operación de arrastre.

El atributo ondragend es parte de la API de Drag and Drop de HTML5 y se activa cuando el usuario finaliza una operación de arrastre (al soltar el elemento). Es esencial para completar acciones como actualizar interfaces, guardar cambios o limpiar recursos después de una operación de arrastre.

¿Cómo funciona?

Disparador:

Cuando el usuario suelta el botón del ratón o levanta el dedo en dispositivos táctiles.

Ciclo del arrastre:

  1. ondragstart: Inicia el arrastre.

  2. ondrag: Durante el movimiento.

  3. ondragend: Finaliza el arrastre (éste evento).

Uso típico:

  • Restaurar estilos modificados durante el arrastre.

  • Confirmar cambios en la interfaz.

  • Liberar recursos o limpiar datos temporales.

Requisitos

  • El elemento debe tener draggable="true".

  • Combinar con eventos como ondragstart y ondragover para un flujo completo.

Sintaxis básica

Como atributo HTML:

<div 
  draggable="true" 
  ondragend="manejarFinArrastre(event)"
>
  Arrástrame
</div>

Con JavaScript (recomendado):

elemento.addEventListener('dragend', (e) => {
  // Acciones al finalizar el arrastre
});

Ejemplos prácticos

Ejemplo 1: Restaurar estilos después del arrastre

<div 
  id="elemento" 
  draggable="true" 
  style="width: 100px; height: 100px; background: blue;"
></div>

<script>
  const elemento = document.getElementById('elemento');

  elemento.addEventListener('dragstart', (e) => {
    e.target.style.opacity = '0.5';
  });

  elemento.addEventListener('dragend', (e) => {
    e.target.style.opacity = '1';
    e.target.style.background = 'green'; // Cambiar color al soltar
  });
</script>

Ejemplo 2: Eliminar elemento arrastrado

<div class="item" draggable="true" ondragend="eliminarSiEnZona(event)">
  ???? Archivo
</div>
<div id="papelera">????️ Papelera</div>

<script>
  function eliminarSiEnZona(e) {
    const papelera = document.getElementById('papelera');
    const rect = papelera.getBoundingClientRect();
    
    // Verificar si el cursor está sobre la papelera
    if (
      e.clientX >= rect.left && 
      e.clientX <= rect.right && 
      e.clientY >= rect.top && 
      e.clientY <= rect.bottom
    ) {
      e.target.remove();
    }
  }
</script>

Ejemplo 3: Guardar posición final

<div 
  id="cajaMovible" 
  draggable="true" 
  style="position: absolute;"
  ondragend="guardarPosicion(event)"
>
  Arrástrame
</div>

<script>
  function guardarPosicion(e) {
    const x = e.clientX;
    const y = e.clientY;
    e.target.style.left = `${x}px`;
    e.target.style.top = `${y}px`;
    localStorage.setItem('posicion', JSON.stringify({ x, y }));
  }
</script>

Propiedades clave del evento ondragend

Accede a datos útiles desde el objeto event:

  • clientX / clientY: Coordenadas finales del cursor.

  • dataTransfer: Datos configurados en ondragstart (si los hay).

  • target: Elemento que fue arrastrado.

Diferencias entre eventos de arrastre

Evento Momento de activación Uso común
ondragstart Inicio del arrastre Configurar datos iniciales
ondrag Durante el arrastre Actualizaciones en tiempo real
ondragend Fin del arrastre Confirmar acciones y limpiar

Mejores prácticas

Siempre restaurar estilos:

elemento.addEventListener('dragend', (e) => {
  e.target.style.cursor = 'default';
  e.target.style.opacity = '1';
});

Validar la zona de destino:

Use document.elementFromPoint() para verificar dónde se soltó el elemento:

elemento.addEventListener('dragend', (e) => {
  const elementoDebajo = document.elementFromPoint(e.clientX, e.clientY);
  if (elementoDebajo.id === 'zonaValida') {
    // Acción válida
  }
});

Manejar datos con dataTransfer:

Configure datos en ondragstart y úselos en ondragend:

elemento.addEventListener('dragstart', (e) => {
  e.dataTransfer.setData('text/plain', 'datoImportante');
});

elemento.addEventListener('dragend', (e) => {
  const dato = e.dataTransfer.getData('text/plain');
  console.log('Dato transferido:', dato);
});

Errores comunes

<!-- MAL: Olvidar draggable="true" -->
<div ondragend="...">No se puede arrastrar</div>

<!-- CONFUSIÓN: Usar ondragend sin ondragstart -->
<div draggable="true" ondragend="..."></div> <!-- dataTransfer estará vacío -->

<!-- BLOQUEAR SIN FEEDBACK VISUAL -->
<script>
  elemento.addEventListener('dragend', (e) => {
    // No se restaura el estilo, el usuario no sabe que terminó
  });
</script>

Compatibilidad

Navegador Soporte Notas
Chrome ✅ Todas versiones  
Firefox ✅ Todas versiones  
Safari ✅ Sí (v. 10+)  
Edge ✅ Sí  
Móviles ⚠️ Limitado Requiere manejo de eventos táctiles

Casos avanzados

Sistema de subida de archivos:

<div id="dropZone">Arrastra archivos aquí</div>

<script>
  const dropZone = document.getElementById('dropZone');

  dropZone.addEventListener('dragover', (e) => {
    e.preventDefault();
  });

  dropZone.addEventListener('drop', (e) => {
    e.preventDefault();
    const archivos = e.dataTransfer.files;
    subirArchivos(archivos);
  });

  function subirArchivos(archivos) {
    // Lógica para subir archivos al servidor
  }
</script>

Juego de rompecabezas:

<div class="pieza" draggable="true" data-posicion="1">????</div>
<div class="tablero" id="tablero"></div>

<script>
  document.querySelectorAll('.pieza').forEach(pieza => {
    pieza.addEventListener('dragend', (e) => {
      const tablero = document.getElementById('tablero');
      const posicionCorrecta = e.target.dataset.posicion === tablero.dataset.objetivo;
      if (posicionCorrecta) {
        e.target.style.background = 'lightgreen';
        tablero.appendChild(e.target);
      }
    });
  });
</script>

Conclusión

El atributo ondragend es crucial para:

  • Completar operaciones de arrastre de manera controlada.
  • Actualizar la UI después de mover elementos.
  • Integrar sistemas complejos como cargas de archivos o juegos.

Recuerda:

  1. Restaura siempre los cambios visuales realizados durante el arrastre.
  2. Combina con dataTransfer para manejar datos eficientemente.
  3. Prueba en móviles y considera alternativas táctiles si es necesario.

¡Ahora puedes crear experiencias de arrastre profesionales y altamente interactivas!