javascript - 有没有办法拖动和复制,但防止 "draggable"下降? (JavaScript)

标签 javascript html drag-and-drop draggable

现在我有一个功能性的拖放和复制。我想知道是否有任何方法可以拖动副本,但不能拖放。例如,如果用户按住 shift 键,他/她可以快速单击并放下克隆而不放下拖动的元素。如果通过文档搜索高低并没有找到任何东西。
这是我的代码 https://jsfiddle.net/jado66/f8b4ms36/2/ :

<!DOCTYPE html>
<html>
<head>
  <title>Drag Copy</title>
</head>
<style>

* {user-select: none; } 
.cell {width:50px;height:50px;
  }
img {width:50px;height:50px;cursor: move;}
table td #dropTable td:hover{background: #dedede;}
#dropTable {
    border-spacing: 5px;
    border: 1px solid #dedede;
}
.droppable:hover{
    transform: scale(1.05);
    transition-duration: 0.3s;
}

#dropTable tbody { height:300px; overflow-y:auto;  }

</style>

<body>
   

     <!-- Drag Table -->
    
        <table style="border-spacing: 5px;">
            <tr>
                <td id="image1">
                    <div class = "cell" ondrop="drop(event)" ondragover="allowDrop(event)">
                        <img class = "droppable newGate" src="droppable" src="https://picsum.photos/500/500?random=1"   
                      ondragstart="dragStart(event)" id="1" draggable="true"/> </div>
                </td>
                <td id="image2">
                    <div class = "cell " ondrop="drop(event)" ondragover="allowDrop(event)">
                        <img class = "droppable" src="https://picsum.photos/500/500?random=2"   
                      ondragstart="dragStart(event)" id="2" draggable="true" /> </div>
                </td>
    
            </tr>
        </table>
        <hr>
        <!-- Drop Table -->
        <table>
            <tr>
                <td>
                    <table id="dropTable" >
                    <tr >
                        <td> <div class = "cell"></div></td> 
                        <td> <div class = "cell" ></div></td>
                        <td> <div class = "cell" ></div></td>
                        <td> <div class = "cell" ></div></td>
                    </tr>
                    <tr>
                        <td> <div class = "cell" ></div></td>
                        <td> <div class = "cell" ></div></td>
                        <td> <div class = "cell" ></div></td>
                        <td> <div class = "cell" ></div></td>
                    </tr>
                    </tr>
                        <td> <div class = "cell" ></div></td>
                        <td> <div class = "cell" ></div></td>
                        <td> <div class = "cell" ></div></td>
                        <td> <div class = "cell" ></div></td>
                    </tr>
                    </table>
                </td>
            </tr>
        </table>
    <script>
    
const cells = document.querySelectorAll(".cell:empty"); //We only want to add event listeners to empty cells
for (const cell of cells){
    cell.addEventListener('dragover',allowDrop);
    cell.addEventListener('drop',drop);
}

function dragStart(evt)
{
    evt.dataTransfer.setData("Text",evt.target.id);
}

function drop(evt)
{
    var data = evt.dataTransfer.getData("Text");
    var nodeCopy = document.getElementById(data).cloneNode(true);
    nodeCopy.id = Date.now(); /* We cannot use the same ID */
    evt.target.appendChild(nodeCopy);
    
    if (evt.shiftKey){
        console.log("Shift key pressed. Copy but keep drag");
      //Invoke drag command, or prevent drop, etc.
    }
}

function allowDrop(ob)
{
    ob.preventDefault();
}
    
    </script>
    </body>
    </html>

最佳答案

简而言之,没有
要回答您的问题,是否可以在用户释放鼠标按钮时阻止 drop 事件:否。
来自 the spec :

Otherwise, if the user ended the drag-and-drop operation (e.g. by releasing the mouse button in a mouse-driven drag-and-drop interface), or if the drag event was canceled, then this will be the last iteration.


然而,当用户放下节点时,可能会立即触发一个新的 DragStart 事件,但我无法让它工作。在规范中找不到任何关于不可能的内容,但我可能是错的。
针对您的特定用例的解决方法
这只是一个概念证明,代码看起来不太好,我确信它有错误,但它可以满足您的要求:https://jsfiddle.net/y9Lpxdea/3/ .按住 shift 键并拖动插槽以克隆当前持有的对象。
通过存储要从 onDragStart 克隆的元素的 id在变量中(不是在 DataTransfer 对象中为 DataTransfer.getData() is only accessible on the drop event ),您可以在 onDragEnter 中访问当前持有对象的 ID事件,然后从那里复制 child 。我保留了当前的拖放功能,而没有保持原样的 shift 键。
let dragId = null;

function dragStart(evt)
{
    evt.dataTransfer.setData("Text",evt.target.id);
    dragId = evt.target.id;
}

function dragEnter(evt)
{
    if (evt.shiftKey && dragId){
        var nodeCopy = document.getElementById(dragId).cloneNode(true);
        nodeCopy.id = Date.now(); /* We cannot use the same ID */
        evt.target.innerHTML = "";
        evt.target.appendChild(nodeCopy);
    }
}

function drop(evt)
{
    var data = evt.dataTransfer.getData("Text");
    var nodeCopy = document.getElementById(data).cloneNode(true);
    nodeCopy.id = Date.now(); /* We cannot use the same ID */
    evt.target.appendChild(nodeCopy);
    dragId = null;
}

关于javascript - 有没有办法拖动和复制,但防止 "draggable"下降? (JavaScript),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67537101/

相关文章:

javascript - Postman 和 Chrome 不同的 API 响应

html - Bootstrap 导航栏 href 到另一个页面不起作用

javascript - 如何使用javascript从输入隐藏类型设置输入类型文件中的值

安卓 : E/InputDispatcher: Window handle drag has no registered input channel

javascript - 使用 grunt 加载 grunt-configs 和 Bower.install()

javascript - 未知错误 - jQuery

javascript - GTM 自定义 html 可以插入某种 id 吗

html - 溢出 CSS 树

javascript - 悬停按钮时显示图像

javascript - HTML 5 拖放到 Firefox 中的所见即所得编辑器