Resumo : neste tutorial, você aprenderá sobre a API JavaScript de arrastar e soltar e como usá-la para implementar um aplicativo simples de arrastar e soltar.
Introdução à API JavaScript Drag and Drop
HTML5 introduziu formalmente a especificação de arrastar e soltar. A maioria dos navegadores modernos implementou arrastar e soltar nativo com base nas especificações HTML5.
Por padrão, apenas imagens e texto podem ser arrastáveis. Para arrastar uma imagem, basta segurar o botão do mouse e movê-la. Para arrastar o texto, você precisa destacar algum texto e arrastá-lo da mesma forma que arrastaria uma imagem.
A especificação HTML5 especifica que quase todos os elementos podem ser arrastáveis. Para tornar um elemento arrastável, você adiciona a draggable
propriedade com o valor true
à sua tag HTML. Por exemplo:
<div class="item" draggable="true"></div>
Linguagem de código: HTML, XML ( xml )
Eventos em elementos arrastáveis
Quando você arrasta um elemento, esses eventos são acionados na seguinte sequência:
dragstart
drag
dragend
Quando você segura o botão do mouse e começa a movê-lo, o dragstart
evento é acionado no elemento arrastável que você está arrastando. O cursor muda para um símbolo de não soltar (um círculo com uma linha atravessando-o) para indicar que você não pode soltar o elemento sobre si mesmo.
Após o dragstart
evento ser acionado, ele drag
será acionado repetidamente enquanto você arrastar o elemento.
E o dragend
evento é acionado quando você para de arrastar o elemento.
O alvo de todos os eventos ( e.target
) é o elemento que está sendo arrastado.
Por padrão, o navegador não altera a aparência do elemento arrastado. Portanto, você pode personalizar sua aparência com base em suas preferências.
Eventos em destinos de lançamento
Quando você arrasta um elemento sobre um destino de soltar válido, esses eventos são acionados na seguinte sequência:
dragenter
dragover
dragleave
oudrop
O dragenter
evento é acionado assim que você arrasta o elemento sobre um destino para soltar.
Após o dragenter
evento ser acionado, dragover
ele será acionado repetidamente enquanto você arrastar o elemento dentro do limite do destino para soltar.
Quando você arrasta o elemento para fora do limite do destino de soltar, o dragover
evento para de ser acionado e o dragleave
evento é acionado.
Caso você solte o elemento no destino, o drop
evento é acionado em vez do dragleave
evento.
O destino ( e.target
) dos eventos dragenter
, dragover
, dragleave
e drop
são os elementos de destino para soltar.
Destino de lançamento válido
Quase todos os elementos suportam os eventos de destino de descarte ( dragenter
, dragover
, dragleave
e drop
). No entanto, eles não permitem a eliminação por padrão.
Se você soltar um elemento sobre um destino de soltura que não permite a queda, o drop
evento não será acionado.
Para transformar um elemento em um destino de descarte válido, você pode substituir o comportamento padrão de ambos dragenter
os dragover
eventos chamando o event.preventDefault()
método em seus manipuladores de eventos correspondentes. (Veja a seção de exemplo para mais informações)
Transferir dados usando o objeto dataTransfer
Para transferir dados em uma ação de arrastar e soltar, você usa o dataTransfer
objeto.
O dataTransfer
objeto é uma propriedade do evento. Ele permite transferir dados do elemento arrastado para o destino de soltar.
O dataTransfer
objeto possui dois métodos: setData()
e getData()
.
O setData()
permite definir os dados da operação de arrastar para o formato e dados especificados:
dataTransfer.setData(format, data)
Linguagem de código: CSS ( css )
O formato pode ser text/plain
ou text/uri-list
. E os dados podem ser uma string representando os dados a serem adicionados ao objeto de arrastar.
O getData()
método recupera os dados de arrastar armazenados pelo setData()
método.
O getData()
aceita um argumento:
dataTransfer(format)
O formato pode ser text/plain
ou text/uri-list
. O getData()
retorna uma string armazenada pelo setData()
método ou uma string vazia se a operação de arrastar não incluir dados.
Exemplo de arrastar e soltar JavaScript
Desenvolveremos o seguinte aplicativo simples de arrastar e soltar para demonstrar a API JavaScript de arrastar e soltar:
Crie a estrutura do projeto
Primeiro, crie uma nova pasta chamada drag-n-drop-basics
. Dentro desta pasta, crie duas subpastas chamadas css
e js
.
Segundo, crie um novo arquivo chamado app.js
na js
pasta, style.css
na css
pasta e index.html
na drag-n-drop-basics
pasta.
Terceiro, coloque o link para a style.css
tag de script e vinculada a app.js
no index.html
arquivo assim:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript - Drag and Drop Demo</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<script src="js/app.js"></script>
</body>
</html>
Linguagem de código: HTML, XML ( xml )
Para o CSS, você pode obtê-lo aqui .
Construa o arquivo index.html
Coloque o seguinte código no index.html
arquivo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript - Drag and Drop Demo</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<h1>JavaScript - Drag and Drop</h1>
<div class="drop-targets">
<div class="box">
<div class="item" id="item">
</div>
</div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
<script src="js/app.js"></script>
</body>
</html>
Linguagem de código: HTML, XML ( xml )
Neste arquivo index.html, usamos o .container
elemento para alinhar o título e drop-targets
o elemento.
Dentro do elemento drop-targets, colocamos três div
elementos com a mesma classe box
. E colocamos outro elemento div com a classe item
na primeira caixa.
Se você abrir index.html
e tentar arrastar a caixa amarela, verá o cursor indicando que não é possível arrastar:
Para tornar o elemento arrastável, adicione a draggable
propriedade com o valor de true
à sua tag HTML da seguinte maneira:
<div class="item" id="item" draggable="true">
Linguagem de código: JavaScript ( javascript )
Agora, se você salvar o index.html
, abri-lo novamente no navegador, você verá que pode arrastar o elemento item assim:
Lidar com eventos no elemento arrastável
O style.css
arquivo possui a .hide
classe que oculta um elemento:
.hide {
display: none;
}
Linguagem de código: CSS ( css )
No app.js
arquivo, você adiciona o seguinte código:
// select the item element
const item = document.querySelector('.item');
// attach the dragstart event handler
item.addEventListener('dragstart', dragStart);
// handle the dragstart
function dragStart(e) {
console.log('drag starts...');
}
Linguagem de código: JavaScript ( javascript )
Como funciona:
- Primeiro, selecione o elemento arrastável usando o arquivo
querySelector()
. - Segundo, anexe um
dragstart
manipulador de eventos ao elemento arrastável. - Terceiro, defina a
dragStart()
função para tratar odragstart
evento.
Se você abrir o arquivo index.html e começar a arrastar o elemento arrastável, verá a drag starts...
mensagem no console.
No dragStart
manipulador de eventos, você precisa armazenar o id
elemento arrastável. E você precisa esconder isso:
function dragStart(e) {
e.dataTransfer.setData('text/plain', e.target.id);
e.target.classList.add('hide');
}
Linguagem de código: JavaScript ( javascript )
Se você arrastar o elemento, verá que ele desaparece assim que você começar a arrastar.
Para resolver isso, você usa a setTimeout()
função:
function dragStart(e) {
e.dataTransfer.setData('text/plain', e.target.id);
setTimeout(() => {
e.target.classList.add('hide');
}, 0);
}
Linguagem de código: JavaScript ( javascript )
Agora você pode arrastar o elemento arrastável para fora de sua posição original:
Lidar com eventos em destinos de descarte
O arquivo style.css também possui uma classe CSS chamada .drag-over
que transforma o estilo da borda do destino para soltar em tracejado e vermelho:
.drag-over {
border: dashed 3px red;
}
Linguagem de código: CSS ( css )
No app.js, você precisa selecionar os elementos de destino para soltar e manipular os eventos dragenter
, dragover
, dragleave
e drop
desses elementos:
const boxes = document.querySelectorAll('.box');
boxes.forEach(box => {
box.addEventListener('dragenter', dragEnter)
box.addEventListener('dragover', dragOver);
box.addEventListener('dragleave', dragLeave);
box.addEventListener('drop', drop);
});
function dragEnter(e) {
}
function dragOver(e) {
}
function dragLeave(e) {
}
function drop(e) {
}
Linguagem de código: JavaScript ( javascript )
O estilo da borda do destino para soltar deve mudar quando o evento dragenter
e dragover
ocorrer. Deve restaurar o estilo quando o evento dragleave
e drop
ocorrer.
Para fazer isso, você adiciona e remove a drag-over
classe do drop
destino assim:
function dragEnter(e) {
e.target.classList.add('drag-over');
}
function dragOver(e) {
e.target.classList.add('drag-over');
}
function dragLeave(e) {
e.target.classList.remove('drag-over');
}
function drop(e) {
e.target.classList.remove('drag-over');
}
Linguagem de código: JavaScript ( javascript )
Agora, se você arrastar o elemento arrastável para outro destino para soltar, verá que a borda do destino para soltar muda conforme mostrado na imagem a seguir:
Para tornar o destino de descarte válido, você precisa chamar event.preventDefault()
os manipuladores de eventos dragenter
e dragover
como este:
function dragEnter(e) {
e.preventDefault();
e.target.classList.add('drag-over');
}
function dragOver(e) {
e.preventDefault();
e.target.classList.add('drag-over');
}
Linguagem de código: JavaScript ( javascript )
Se você não fizer isso, o drop
evento nunca será acionado porque o div
elemento não é um destino de descarte válido por padrão.
Se você arrastar o elemento arrastável para um destino para soltar, verá que o cursor muda indicando que você pode soltar o elemento:
Agora, se você descartar o elemento item, verá que ele desaparece imediatamente.
Para resolver esse problema, você precisa adicionar o identificador do drop
evento.
- Primeiro, obtenha o
id
elemento arrastável usando ogetData()
método dodataTransfer
objeto. - Segundo, anexe o elemento arrastável como um elemento filho do elemento de destino para soltar.
- Terceiro, remova a
hide
classe dodraggable
elemento.
O código a seguir mostra o drop
manipulador de eventos completo:
function drop(e) {
e.target.classList.remove('drag-over');
// get the draggable element
const id = e.dataTransfer.getData('text/plain');
const draggable = document.getElementById(id);
// add it to the drop target
e.target.appendChild(draggable);
// display the draggable element
draggable.classList.remove('hide');
}
Linguagem de código: JavaScript ( javascript )
Se você arrastar e soltar o elemento arrastável agora, ele deverá funcionar conforme o esperado.
O seguinte mostra o arquivo app.js completo:
/* draggable element */
const item = document.querySelector('.item');
item.addEventListener('dragstart', dragStart);
function dragStart(e) {
e.dataTransfer.setData('text/plain', e.target.id);
setTimeout(() => {
e.target.classList.add('hide');
}, 0);
}
/* drop targets */
const boxes = document.querySelectorAll('.box');
boxes.forEach(box => {
box.addEventListener('dragenter', dragEnter)
box.addEventListener('dragover', dragOver);
box.addEventListener('dragleave', dragLeave);
box.addEventListener('drop', drop);
});
function dragEnter(e) {
e.preventDefault();
e.target.classList.add('drag-over');
}
function dragOver(e) {
e.preventDefault();
e.target.classList.add('drag-over');
}
function dragLeave(e) {
e.target.classList.remove('drag-over');
}
function drop(e) {
e.target.classList.remove('drag-over');
// get the draggable element
const id = e.dataTransfer.getData('text/plain');
const draggable = document.getElementById(id);
// add it to the drop target
e.target.appendChild(draggable);
// display the draggable element
draggable.classList.remove('hide');
}
Linguagem de código: JavaScript ( javascript )
E aqui está o link para a demonstração .
Resumo
- Adicione a
draggable
propriedade com o valor true a um elemento para torná-lo arrastável. - Os eventos
dragstart
,drag
edragend
são acionados no elemento arrastável. - Os eventos
dragenter
,dragover
,dragleave
oudrop
são acionados no destino de soltar. - Chame os
event.preventDefault()
manipuladores de eventosdragenter
edragover
para tornar um elemento um destino de descarte válido. - Use o
event.dataTransfer
objeto com os métodossetData()
egetData()
para transferir dados na operação de arrastar e soltar.