Reputation: 1
I'm trying to make a drag and drop API to use in my website.
The drag part is working, but when I drop the element on the target div
, that div
only disappears.
HTML
CSS
Java Script
const draggables = document.querySelectorAll('.draggable');
const dropables = document.querySelectorAll('.dropable');
//Event Listeners
draggables.forEach(draggable =>{
draggable.addEventListener('dragstart', dragStart)
draggable.addEventListener('dragend', dragEnd)
})
dropables.forEach(dropable=>{
dropable.addEventListener('dragenter', dragEnter);
dropable.addEventListener('dragover', dragOver);
dropable.addEventListener('dragleave', dragLeave);
dropable.addEventListener('drop', dragDrop);
})
//Funções
function dragStart(){
this.className +=' hold';
setTimeout(() => (this.className = 'desabilitado'), 0);
this.parentElement.className = 'dropable';
let clone = this.lastChild.cloneNode(true);
this.parentElement.appendChild(clone)
}
function dragEnd(){
this.className = 'draggable'
this.parentElement.className = ' ';
this.parentElement.lastChild.remove();
}
function dragOver(e) {
e.preventDefault();
}
function dragEnter(e) {
e.preventDefault();
this.className += ' hovered';
}
function dragLeave() {
this.className = 'dropable';
}
function dragDrop() {
this.className = ' ';
const holded = document.querySelector('.hold');
this.appendChild(holded);
}
.dragdroparea{
display: flex;
flex-direction: row;
position: relative;
align-items: center;
justify-content: center;
z-index: 50;
height: 60vh;
width: 80vw;
}
.coluna{
display: flex;
flex-direction: column;
overflow-y: scroll;
width: 37vw;
height: 56vh;
}
.linha{
display: flex;
flex-direction: row;
margin-bottom: 1vw;
}
.draggable{
position: relative;
width: 3vw;
height: 2vw;
border-radius: 7px;
background-color: #e25f07;
display: flex;
justify-content: center;
align-items: center;
color: white;
margin-right: 0.5vw;
cursor: move;
z-index: 10000;
}
.dropable{
position: relative;
width: 3vw;
height: 2vw;
border-radius: 7px;
border-color: #e25f07;
border-style: dashed;
border-width: 2.3px;
background-color: white;
display: flex;
justify-content: center;
align-items: center;
margin-right: 0.5vw;
z-index: 500;
color: #e25f07;
}
.resposta{
margin-right: 1vw;
}
.textodrag{
width: 31vw;
}
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-button {
width: 0px;
height: 0px;
}
::-webkit-scrollbar-thumb {
background: #e25f07;
border: 0px none #ffffff;
border-radius: 38px;
}
::-webkit-scrollbar-thumb:hover {
background: #f58d47;
}
::-webkit-scrollbar-thumb:active {
background: #e25f07;
}
::-webkit-scrollbar-track {
background: #ebe8e6;
border: 0px none #ffffff;
border-radius: 55px;
}
::-webkit-scrollbar-track:hover {
background: #e8e6df;
}
::-webkit-scrollbar-track:active {
background: #e8e6df;
}
::-webkit-scrollbar-corner {
background: transparent;
}
.invisible{
display: none;
}
.hovered{
width: 3.5vw;
height: 2.5vw;
}
.hold {
border: solid 5px #ccc;
}
.desabilitado{
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./teste2.css">
</head>
<body>
<div class="slide active">
<div class="conteudovertical">
<p class="header1" style="line-height: 20%;">Garantias e direitos dos participantes de pesquisa</p><br>
<p class="rodape1">Agora, arraste todos os direitos dos participantes na caixa ao lado.</p>
<div class="dragdroparea">
<div class="coluna resposta">
<div class="linha">
<div>
<div draggable="true" class="draggable"><p>1</p></div>
</div>
<div class="textodrag">
<p>Receber as informações do estudo de forma
claras</p>
</div>
</div>
<div class="linha">
<div>
<div draggable="true" class="draggable"><p>2</p></div>
</div>
<div class="textodrag">
<p>Ter oportunidade de esclarecer dúvidas</p>
</div>
</div>
</div>
<div class="coluna">
<div class="linha">
<div class="dropable"></div>
<div class="textodrag">
<p>A linguagem utilizada tanto na redação do
TCLE quanto no processo de consentimento deve
ser adequada a população do estudo.</p>
</div>
</div>
<div class="linha">
<div class="dropable"></div>
<div class="textodrag">
<p>Durante o processo de consentimento, e a
qualquer momento, o participante deve poder
esclarecer quaisquer dúvidas relativas ao estudo e
ao seu tratamento.</p>
</div>
</div>
</div>
</div>
</div>
<script src="./scripts/dragAndDrop.js"></script>
</body>
</html>
Upvotes: 0
Views: 1715
Reputation: 21
It seems that the problem comes from the fact that you are adding the hold
class to "this", but cloning a child of this node. So, when the timeout's callback execute at the next cycle, you're basically changing the class of the only element that has the hold
class. Then when you try to find that element via querySelector
, it can't find it.
If instead of adding that class to "this", you add it to the clone for example:
clone.className += " hold";
, just after you clone it, then your dragdrop
function will be able to find it appropriately and move it to the right place.
I guess you probably want to clone the whole element instead of the last child though, or NOT change the class of the '.dropable' element when dropping into it, as the style is going to be off (I guess you'll figure what you want to do exactly from there).
Edit: I was playing with it a little on a personal sandbox, and sometimes the dragEnd event is being fired immediatly. I found this other thread where someone explains that it's because you're modifying the DOM in dragStart, and instead you should do it in dragEnter: https://stackoverflow.com/a/19663227/2998036
Upvotes: 1