0Pricing
HTML Academy · Lección

Lista práctica con reordenación mediante arrastre

Cree una lista reordenable con la API Drag and Drop

Lista práctica con reordenación mediante arrastre es una lección gratuita de HTML Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de HTML Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de HTML Academy incluye 4 lecciones en total.

Descripción general del patrón

Para crear una lista reordenable mediante arrastre, haga que cada elemento sea arrastrable, almacene el id del elemento arrastrado en dataTransfer durante dragstart y, al soltar, inserte el elemento arrastrado antes o después del destino. El DOM y el modelo se mantienen sincronizados si reconstruye el orden a partir del DOM después de cada suelta.

Marcado

Renderice una lista plana en la que cada li incluya draggable="true" y un data-id. Mantener los id en los elementos significa que los controladores de arrastre no necesitan consultar un almacén de estado separado para identificar los elementos: el propio elemento es la fuente de verdad.

<ul id="list">
  <li draggable="true" data-id="1">Item 1</li>
  <li draggable="true" data-id="2">Item 2</li>
  <li draggable="true" data-id="3">Item 3</li>
</ul>

dragstart registra el origen

Durante dragstart, almacene el id del elemento arrastrado en dataTransfer y aplique una clase "dragging" para proporcionar información visual. effectAllowed="move" indica al navegador que se trata de un reordenamiento, no de una copia, por lo que el cursor y dropEffect reflejan una operación de movimiento.

list.addEventListener("dragstart", (e) => {
  const li = e.target.closest("li");
  if (!li) return;
  e.dataTransfer.setData("text/plain", li.dataset.id);
  e.dataTransfer.effectAllowed = "move";
  li.classList.add("dragging");
});

dragover permite la suelta

Escuche en la lista (delegación de eventos), llame a preventDefault y establezca dropEffect en "move". Use e.target.closest("li") para encontrar la fila sobre la que se encuentra el cursor, de modo que el mismo controlador funcione para toda la lista.

Cálculo de la posición de inserción

Para decidir si el elemento arrastrado debe quedar encima o debajo de la fila sobre la que se encuentra el cursor, compare la coordenada Y del cursor con el punto medio vertical de la fila: const before = (e.clientY - rect.top) < rect.height / 2. before=true significa insertBefore y false significa insertAfter.

function getInsertBefore(target, clientY) {
  const rect = target.getBoundingClientRect();
  return clientY < rect.top + rect.height / 2;
}

drop reordena el DOM

En el controlador de drop, busque el elemento arrastrado mediante su id y la fila de destino que está bajo el cursor. Llame a list.insertBefore(dragged, target) o list.insertBefore(dragged, target.nextSibling) según la mitad del destino sobre la que se encuentre el cursor.

dragend limpia los estilos

Tanto si la suelta se realizó correctamente como si el usuario pulsó Escape, dragend siempre se activa en el origen. Úselo para eliminar la clase "dragging" y cualquier resaltado del destino de la suelta, de modo que la lista vuelva a su estado inactivo.

list.addEventListener("dragend", () => {
  list.querySelectorAll(".dragging, .over").forEach((el) => {
    el.classList.remove("dragging", "over");
  });
});

Indicador visual de suelta

Muestre una línea fina donde se colocará el elemento mediante un pseudo-elemento CSS en la fila sobre la que se encuentra el cursor. Actívela con una clase "over-top" o "over-bottom" que el controlador de dragover establezca según la posición del cursor. El usuario verá el punto de inserción antes de soltar el elemento.

Sincronización del modelo

Después de la suelta, obtenga el nuevo orden a partir del DOM: const order = Array.from(list.children).map((li) => li.dataset.id). Envíe ese array al servidor o guárdelo en el estado; nunca intente mantener un índice paralelo junto al DOM, ya que se desincroniza con arrastres rápidos.

Alternativa con teclado

Añada controladores Up/Down que muevan el elemento enfocado mediante insertBefore. Anuncie el movimiento a través de una región aria-live ("Elemento movido hacia arriba a la posición 2"). Los usuarios de teclado obtienen la misma capacidad sin tener que realizar un arrastre visual, algo esencial para la accesibilidad.

Alternativa compatible con dispositivos táctiles

En dispositivos móviles, sustituya el arrastre nativo por Pointer Events: durante pointerdown capture la fila; durante pointermove, muévala con CSS transform; y durante pointerup, identifique mediante hit-testing la fila subyacente y reordene los elementos. Bibliotecas como SortableJS encapsulan este patrón para distintos tipos de entrada.

Comprobación de conocimientos

¿Por qué calculamos la posición de inserción a partir de la posición del cursor respecto al punto medio vertical de la fila sobre la que se encuentra?

Resumen

Una lista reordenable sólida combina draggable="true" + dragstart (registrar el id, effectAllowed=move) + dragover (preventDefault + posición del indicador) + drop (insertBefore en la posición calculada a partir del punto medio) + dragend (limpieza). Obtenga siempre el nuevo orden a partir del DOM después de la suelta y proporcione una alternativa con teclado para garantizar la accesibilidad.

Preguntas frecuentes

¿La lección «Lista práctica con reordenación mediante arrastre» es gratis?

Sí — el texto completo de «Lista práctica con reordenación mediante arrastre» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de HTML Academy, actualiza a CoddyKit PRO. El curso de HTML Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Lista práctica con reordenación mediante arrastre»?

Cree una lista reordenable con la API Drag and Drop Practicas HTML Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar HTML Academy?

No se requiere experiencia previa. HTML Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Lista práctica con reordenación mediante arrastre»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de HTML Academy?

Sí. Cada lección de HTML Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Atributo draggable y evento dragstart
  2. Eventos dragover y drop
  3. Objeto dataTransfer
  4. Lista práctica con reordenación mediante arrastre
← Volver a HTML Academy