有没有办法拖动和复制,但用 "draggable" 防止掉落? (JavaScript)
Is there a way to drag and copy, but prevent the drop with "draggable"? (JavaScript)
现在我有一个功能性的拖动和复制。我想知道是否有任何方法可以拖动副本,但不能放下。例如,如果用户按住 shift 键,he/she 可以快速单击并放下克隆,而不会放下被拖动的元素。如果通过文档上下搜索并没有找到任何东西。
这是我的代码 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>
简而言之,没有
回答您的问题是否可以在用户释放鼠标按钮时阻止拖放事件:否。
来自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 事件,但我无法让它工作。在规范中找不到任何关于不可能的内容,但我可能是错的。
针对您的特定用例的解决方法
这只是一个概念验证 fiddle,代码看起来不太好,我敢肯定它有错误,但它可以满足您的要求:https://jsfiddle.net/y9Lpxdea/3/。按住您的 shift 键并在插槽上拖动以克隆当前 object 所持有的。
通过将要从 onDragStart
克隆的元素的 ID 存储在变量中(不在 DataTransfer object 中,因为 DataTransfer.getData() is only accessible on the drop
event) 您可以在 onDragEnter
事件中访问当前持有的 object 的 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;
}
现在我有一个功能性的拖动和复制。我想知道是否有任何方法可以拖动副本,但不能放下。例如,如果用户按住 shift 键,he/she 可以快速单击并放下克隆,而不会放下被拖动的元素。如果通过文档上下搜索并没有找到任何东西。
这是我的代码 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>
简而言之,没有
回答您的问题是否可以在用户释放鼠标按钮时阻止拖放事件:否。
来自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 事件,但我无法让它工作。在规范中找不到任何关于不可能的内容,但我可能是错的。
针对您的特定用例的解决方法
这只是一个概念验证 fiddle,代码看起来不太好,我敢肯定它有错误,但它可以满足您的要求:https://jsfiddle.net/y9Lpxdea/3/。按住您的 shift 键并在插槽上拖动以克隆当前 object 所持有的。
通过将要从 onDragStart
克隆的元素的 ID 存储在变量中(不在 DataTransfer object 中,因为 DataTransfer.getData() is only accessible on the drop
event) 您可以在 onDragEnter
事件中访问当前持有的 object 的 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;
}