Atributo draggable do HTML
O atributo HTML draggable especifica se um elemento pode ser arrastado pelo usuário. Saiba seus valores e como usá-lo com a API de Drag and Drop.
O atributo HTML draggable é um atributo enumerado que especifica se um elemento pode ser arrastado pelo usuário com um dispositivo apontador (mouse ou toque). Ele é o ponto de entrada da API de Drag and Drop do HTML, que permite mover elementos, textos, arquivos ou dados personalizados de um lugar da página para outro.
Definir draggable="true" apenas torna o elemento selecionável para arrastar. Para de fato mover algo e soltá-lo em um lugar útil, você também precisa tratar os eventos de arrastar e soltar e transportar informações pelo objeto dataTransfer — ambos abordados abaixo.
Você pode usar este atributo em qualquer elemento HTML. Ele faz parte dos Atributos Globais, portanto funciona junto com outros atributos globais, como contenteditable.
Valores
O atributo draggable pode ter os seguintes valores:
true— o elemento pode ser arrastado.false— o elemento não pode ser arrastado. Útil para desativar o comportamento padrão de arrastar imagens e links.auto— usa o comportamento padrão do navegador para esse elemento. Na prática, isso significa que imagens e links são arrastáveis, e a maioria dos outros elementos não é. Comoautosimplesmente mantém o padrão, raramente é escrito explicitamente; omitirdraggableproduz o mesmo resultado.
<tag draggable="true|false|auto"></tag>Nota:
draggablenão é um atributo boolean. Você deve escrever o valor explicitamente —draggablesozinho oudraggable=""é inválido. Use sempredraggable="true"oudraggable="false".
Como funciona o drag and drop
Uma interação de arrastar e soltar dispara uma sequência de eventos, divididos entre o elemento sendo arrastado (a origem) e o elemento sobre o qual ele é solto (o alvo):
| Evento | Dispara em | Quando |
|---|---|---|
dragstart | origem | O usuário começa a arrastar o elemento. Defina seus dados aqui com dataTransfer.setData(). |
drag | origem | Repetidamente enquanto o elemento está sendo arrastado. |
dragenter | alvo | O elemento arrastado entra em um alvo de soltura válido. |
dragover | alvo | Repetidamente enquanto o elemento está sobre um alvo de soltura. Chame preventDefault() aqui. |
dragleave | alvo | O elemento arrastado sai do alvo de soltura. |
drop | alvo | O elemento é liberado sobre o alvo. Leia seus dados aqui com dataTransfer.getData(). |
dragend | origem | O arrasto termina (seja ele concluído com sucesso ou cancelado). |
O objeto dataTransfer
Todo evento de drag expõe event.dataTransfer, o canal usado para passar dados da origem ao alvo:
event.dataTransfer.setData(format, data)— armazena uma string durantedragstart. Oformatgeralmente é um tipo MIME como"text/plain"(código mais antigo usa"Text", que ainda funciona).event.dataTransfer.getData(format)— lê essa string de volta durantedrop.
Como os dados só ficam disponíveis no drop, o padrão típico é armazenar o id de um elemento (ou qualquer identificador) no dragstart e depois localizá-lo e movê-lo no drop.
Por que preventDefault() é obrigatório
Por padrão, a maioria dos elementos não é um alvo de soltura válido, então o navegador cancela a operação. Para tornar um elemento uma zona de soltura, você deve chamar event.preventDefault() no seu manipulador dragover — isso diz ao navegador "sim, uma soltura é permitida aqui." Também é comum chamar preventDefault() no manipulador drop para impedir a ação padrão do navegador (por exemplo, navegar para um link arrastado ou abrir um arquivo solto).
Se você esquecer preventDefault() no dragover, o evento drop nunca dispara e nada acontece.
Exemplo (manipuladores inline)
Este exemplo usa atributos de manipuladores de eventos inline (ondragstart, ondragover, ondrop). É conciso, mas mistura JavaScript com a marcação:
<!DOCTYPE HTML>
<html>
<head>
<title>Title of the document</title>
<style>
#rectId {
width: 350px;
height: 70px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</style>
<script>
function allowDrop(event) {
event.preventDefault(); // Allow dropping
}
function drag(event) {
// Store the dragged element's ID in the dataTransfer object
event.dataTransfer.setData("text/plain", event.target.id);
}
function drop(event) {
event.preventDefault();
var data = event.dataTransfer.getData("text/plain"); // Retrieve the ID
event.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>
<div id="rectId" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br />
<p id="dragId" draggable="true" ondragstart="drag(event)">
This is a draggable paragraph. Drag this item to the rectangle.
</p>
</body>
</html>Exemplo (com addEventListener moderno)
Para um código de fácil manutenção, mantenha a marcação limpa e adicione os manipuladores em JavaScript com addEventListener. Esta é a abordagem recomendada:
<!DOCTYPE HTML>
<html>
<head>
<title>Title of the document</title>
<style>
#dropzone {
width: 350px;
height: 70px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</style>
</head>
<body>
<div id="dropzone"></div>
<br />
<p id="item" draggable="true">
This is a draggable paragraph. Drag this item to the rectangle.
</p>
<script>
const item = document.getElementById("item");
const dropzone = document.getElementById("dropzone");
// Source: store the dragged element's ID when the drag begins.
item.addEventListener("dragstart", (event) => {
event.dataTransfer.setData("text/plain", event.target.id);
});
// Target: allow dropping by preventing the default handling.
dropzone.addEventListener("dragover", (event) => {
event.preventDefault();
});
// Target: move the element into the drop zone.
dropzone.addEventListener("drop", (event) => {
event.preventDefault();
const id = event.dataTransfer.getData("text/plain");
const dragged = document.getElementById(id);
event.currentTarget.appendChild(dragged);
});
</script>
</body>
</html>Acessibilidade
O atributo draggable não oferece suporte a teclado ou leitor de tela por si só — arrastar e soltar é uma interação exclusiva por ponteiro. Usuários que navegam por teclado ou tecnologia assistiva não conseguem executar um arrasto nativo.
Se arrastar e soltar for a única maneira de concluir uma ação, ofereça sempre uma alternativa acessível (por exemplo, botões "Mover para cima / Mover para baixo", um menu de seleção ou copiar/colar). Trate o drag and drop nativo como um aprimoramento, não como o único caminho.