Arrastar e Soltar com a Drag and Drop API em JavaScript
A Drag-and-Drop API permite que elementos sejam arrastados com o mouse e posicionados em locais específicos em uma página web. Durante o processo, identificamos dois elementos principais:
- Fonte do arrasto: o elemento que está sendo arrastado.
- Alvo do arrasto: o elemento ou área onde o item será solto.
Para tornar um elemento arrastável, basta adicionar o atributo draggable com o valor true. Qualquer elemento na página pode se tornar arrastável. Veja o exemplo abaixo:
<div style="width:50px; height:50px; background-color: red;" draggable="true"></div>Por padrão, os elementos HTML não são arrastáveis. Já o alvo do arrasto pode ser qualquer elemento HTML configurado para receber os eventos apropriados.
Eventos do Drag-and-Drop
Ao arrastar e soltar um elemento, diversos eventos são disparados em diferentes momentos:
dragstart: disparado quando o arrasto começa.drag: disparado continuamente enquanto o elemento está sendo arrastado.dragend: disparado quando o arrasto termina.dragenter: disparado quando o elemento entra na área do alvo.dragover: disparado continuamente enquanto o elemento está sobre o alvo.dragleave: disparado quando o elemento sai do alvo.drop: disparado quando o elemento é solto no alvo.
Esses eventos recebem um objeto DragEvent como parâmetro, que herda propriedades dos objetos MouseEvent e Event.
O exemplo a seguir define um elemento arrastável e registra eventos para capturar as ações de arrasto e soltura.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exemplo Drag-and-Drop</title>
<style>
#source {
width: 50px;
height: 50px;
background-color: red;
display: inline-block;
}
#target {
width: 200px;
height: 150px;
overflow: hidden;
border: #ccc 1px dashed;
}
div {
margin: 5px;
}
</style>
</head>
<body>
<div id="source" draggable="true"></div>
<div id="target"></div>
<script>
const source = document.getElementById("source");
source.addEventListener("dragstart", () => console.log("Arrasto iniciado"));
const target = document.getElementById("target");
target.addEventListener("dragover", (event) => {
event.preventDefault();
console.log("Elemento sobre o alvo");
});
target.addEventListener("drop", () => console.log("Elemento solto"));
</script>
</body>
</html>Nesse exemplo:
dragstarté disparado ao iniciar o arrasto do elementosource.dragoveré disparado enquanto o elemento source está sobre o alvotarget. O métodopreventDefault()é chamado para habilitar soltar o elemento no alvo.dropé disparado ao soltar o elemento no alvo.

No próximo exemplo, uma cópia do elemento arrastado é adicionada ao alvo.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exemplo Drag-and-Drop</title>
<style>
#source {
width: 50px;
height: 50px;
background-color: red;
display: inline-block;
}
#target {
width: 200px;
height: 150px;
overflow: hidden;
border: #ccc 1px dashed;
}
div {
margin: 5px;
}
</style>
</head>
<body>
<div id="source" draggable="true"></div>
<div id="target"></div>
<script>
let dragged = null;
const source = document.getElementById("source");
source.addEventListener("dragstart", (e) => (dragged = e.target));
const target = document.getElementById("target");
target.addEventListener("dragover", (e) => e.preventDefault());
target.addEventListener("drop", (e) => e.target.appendChild(dragged.cloneNode(true)));
</script>
</body>
</html>Neste exemplo:
- A referência ao elemento arrastado é armazenada na variável
draggeddurante odragstart. - No evento
drop, uma cópia do elemento original é criada usandocloneNode(true)e adicionada aotarget.
O resultado de adicionar cópias do elemento arrastado ao alvo é mostrado na imagem a seguir.

O exemplo a seguir mostra como mover o elemento original para o alvo, em vez de criar uma cópia.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exemplo Drag-and-Drop</title>
<style>
#container {
width: 60px;
height: 60px;
}
#source {
width: 50px;
height: 50px;
background-color: red;
display: inline-block;
}
#target {
width: 200px;
height: 150px;
overflow: hidden;
border: #ccc 1px dashed;
}
div {
margin: 5px;
}
</style>
</head>
<body>
<div id="container"><div id="source" draggable="true"></div></div>
<div id="target"></div>
<script>
let dragged = null;
const source = document.getElementById("source");
source.addEventListener("dragstart", (e) => (dragged = e.target));
const target = document.getElementById("target");
target.addEventListener("dragover", (e) => e.preventDefault());
target.addEventListener("drop", (e) => {
dragged.parentNode.removeChild(dragged);
e.target.appendChild(dragged);
});
</script>
</body>
</html>O resutado de mover o elemento arrastado para o alvo é mostrado na imagem a seguir.

Documentação oficial: