如何使用 HTML/CSS 拖放元素?



我正在尝试制作一个拖放 API 以在我的网站中使用。

拖动部分正在工作,但是当我将元素放在目标div上时,该div只会消失。

.HTML

https://codeshare.io/5Dx4XW

.CSS

https://codeshare.io/aVxw89

爪哇脚本

https://codeshare.io/GqZWOA

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>

问题似乎来自这样一个事实,即您将hold类添加到"this",但克隆此节点的子节点。因此,当超时的回调在下一个周期执行时,您基本上是在更改具有hold类的唯一元素的类。然后当你试图通过querySelector找到该元素时,它找不到它。

如果不是将该类添加到"this",而是将其添加到克隆中,例如:clone.className += " hold";,就在克隆它之后,您的dragdrop函数将能够适当地找到它并将其移动到正确的位置。 我猜你可能想克隆整个元素而不是最后一个孩子,或者在放入它时不更改".dropable"元素的类,因为样式将关闭(我想你会弄清楚你想做什么确切地从那里(。

编辑:我在个人沙盒上玩了一下,有时 dragEnd 事件会立即触发。我发现了另一个线程,有人解释说这是因为您在 dragStart 中修改了 DOM,而是您应该在 dragEnter 中执行此操作: https://stackoverflow.com/a/19663227/2998036

最新更新