Acabei de aprender o básico da API arrastável e solta do HTML5. Não sei como manter a posição arrastada em sua posição solta. Ao deixá-lo cair, ele muda de posição.
Aqui está o HTML básico (apenas elementos relevantes):
onDragStart = function(ev) {
//...
}
drop_handler = function(ev) {
ev.preventDefault();
ev.target.appendChild(document.getElementById("id1"));
}
dragover_handler = function(ev) {
ev.preventDefault();
ev.dataTransfer.dropEffect = "move";
}
<div id="id1" draggable="true" ondragstart="onDragStart(event)" style="border:2px solid green; cursor:pointer;width:100px;height:50px;">Dragged Div</div>
<div id="id2" style="position:absolute;left:100px;top:200px;border:2px solid red; cursor:pointer;width:200px;height:200px;" ondrop="drop_handler(event)" ondragover="dragover_handler(event)">Drop Div
</div>
Quero que o elemento arrastado permaneça em sua posição final onde foi solto. Quaisquer sugestões serão apreciadas.
Como mencionei no meu comentário, <div id="id1" ...>
ainda tem o posicionamento padrão que é static
. Depois de anexá-lo ao dropDiv, ele assume o comportamento normal do fluxo de documentos. Por ser um elemento de bloco, ele fica abaixo do texto que já está lá e preenche a largura do bloco.
Se você quiser que ele fique exatamente onde está ao soltá-lo, você precisa dar position: absolute
e levar em consideração como o mouse se move ao arrastá-lo na tela. Nesse dragStart
caso, capturamos as coordenadas originais do dragDiv e consideramos onde o mouse estava dentro em relação ao canto superior esquerdo. Quando soltamos o dragDiv no dropDiv, definimos o posicionamento absoluto e consideramos quanto o mouse se moveu durante o arrasto.
Como dragDiv agora é filho de dropDiv, precisamos que nossos novos valores de topo e esquerda sejam relativos às coordenadas de dropDiv em vez de toda a tela, então subtraímos os valores de topo e esquerda de dropDiv. Observe bem que alguns desses métodos podem não levar em conta as bordas ao redor dos elementos, o que pode fazer com que pareça que estão um ou dois pixels fora - para corrigir isso, você pode subtrair um ou dois pixels no cálculo ou fornecê-los box-sizing: border-box
.
let offsetX;
let offsetY;
onDragStart = function(ev) {
const rect = ev.target.getBoundingClientRect();
offsetX = ev.clientX - rect.x;
offsetY = ev.clientY - rect.y;
};
drop_handler = function(ev) {
ev.preventDefault();
const left = parseInt(id2.style.left);
const top = parseInt(id2.style.top);
id1.style.position = 'absolute';
id1.style.left = ev.clientX - left - offsetX + 'px';
id1.style.top = ev.clientY - top - offsetY + 'px';
id2.appendChild(document.getElementById("id1"));
};
dragover_handler = function(ev) {
ev.preventDefault();
ev.dataTransfer.dropEffect = "move";
};
<div id="id1" draggable="true" ondragstart="onDragStart(event)" style="border:2px solid green; cursor:pointer;width:100px;height:50px;">Dragged Div</div>
<div id="id2" style="position:absolute;left:200px;top:50px;border:2px solid red; cursor:pointer;width:200px;height:200px;" ondrop="drop_handler(event)" ondragover="dragover_handler(event)">Drop Div
</div>
Este artigo é coletado da Internet.
Se houver alguma infração, entre em [email protected] Delete.
deixe-me dizer algumas palavras