【问题标题】:How can I drag and drop elements with HTML/CSS?如何使用 HTML/CSS 拖放元素?
【发布时间】:2020-06-23 05:01:21
【问题描述】:

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

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

HTML

https://codeshare.io/5Dx4XW

CSS

https://codeshare.io/aVxw89

Java 脚本

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>

【问题讨论】:

  • 欢迎来到 SO!作为新访客,我建议您查看How to Ask。一些快速提示:通常最好将您的代码包含在问题正文中,而不是链接到某些外部源。另外,尽量将该代码表示​​为minimal reproducible example。欢迎来到这个网站,祝你好运,编码愉快!

标签: javascript html css drag-and-drop draggable


【解决方案1】:

似乎问题出在您将hold 类添加到“this”中,但克隆了该节点的一个子节点。因此,当超时的回调在下一个周期执行时,您基本上是在更改唯一具有 hold 类的元素的类。然后当您尝试通过querySelector 查找该元素时,它找不到它。

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

编辑:我在个人沙箱上玩了一下,有时会立即触发 dragEnd 事件。我发现this other thread有人解释说这是因为你在dragStart中修改DOM,而不是你应该在dragEnter中进行: https://stackoverflow.com/a/19663227/2998036

【讨论】:

  • 我已经重新制作了 js 并且我实现了这个 codeshare.io/2WB9QE 但它仍然有一些问题,比如我希望它能够返回被拖到其原始位置的项目 i.imgur.com/H0CPXMh.gif跨度>
  • 你可以这样做,但你必须改变一些事情。首先,您最初的“1”和“2”必须具有“可丢弃”类(以及检查可以放入其中的内容,见下文)。您基本上想要对右侧的可放置区域执行相同的操作,只是它们会有所不同:1)在它们为空之前您不能放入它们 2)您只能退回相同的他们最初的号码。对于第一点,您可以添加一个类似的可放置类(请注意,您必须在之后添加事件处理程序)。
  • 对于第二点,您可以在拖出时隐藏数字(而不是删除它),然后如果您将元素拖入其中,请检查它是否是相同的数字 - 如果是,然后你完成下降,如果没有,你取消它。您还可以在构建事件处理程序时以不同的方式考虑问题并处理该逻辑,方法是在某处创建所有逻辑并根据您收到的元素引用它。
  • 附带说明,您应该使用传递给您的处理程序的事件,而不是为每个事件处理程序创建一个新的匿名函数:item.addEventListener("dragend", function(event) { const element = event.target ... } 您还可以使用一个不错的 ES6 箭头函数:@ 987654330@。稍微改变一下命名 (list_items -> draggableItems) (lists -> droppableItems) 也会有帮助,这样更容易理解发生了什么。
猜你喜欢
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 2017-08-07
  • 2022-01-22
  • 2013-06-18
  • 2017-11-12
  • 2013-08-10
  • 1970-01-01
相关资源
最近更新 更多