W3docs

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 é. Como auto simplesmente mantém o padrão, raramente é escrito explicitamente; omitir draggable produz o mesmo resultado.
<tag draggable="true|false|auto"></tag>

Nota: draggable não é um atributo boolean. Você deve escrever o valor explicitamente — draggable sozinho ou draggable="" é inválido. Use sempre draggable="true" ou draggable="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):

EventoDispara emQuando
dragstartorigemO usuário começa a arrastar o elemento. Defina seus dados aqui com dataTransfer.setData().
dragorigemRepetidamente enquanto o elemento está sendo arrastado.
dragenteralvoO elemento arrastado entra em um alvo de soltura válido.
dragoveralvoRepetidamente enquanto o elemento está sobre um alvo de soltura. Chame preventDefault() aqui.
dragleavealvoO elemento arrastado sai do alvo de soltura.
dropalvoO elemento é liberado sobre o alvo. Leia seus dados aqui com dataTransfer.getData().
dragendorigemO 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 durante dragstart. O format geralmente é um tipo MIME como "text/plain" (código mais antigo usa "Text", que ainda funciona).
  • event.dataTransfer.getData(format) — lê essa string de volta durante drop.

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.

Prática

Prática
O que é verdade sobre o atributo HTML draggable?
O que é verdade sobre o atributo HTML draggable?
Was this page helpful?