开始拖拽一个带有 draggable 属性的 DOM 元素后,我们可以停止拖拽并退出拖拽操作吗?

Posted

技术标签:

【中文标题】开始拖拽一个带有 draggable 属性的 DOM 元素后,我们可以停止拖拽并退出拖拽操作吗?【英文标题】:After starting the drag of a DOM element with draggable attribute , Could we stop dragging and exit from drag and drop? 【发布时间】:2021-10-20 20:52:17 【问题描述】:

开始拖动后,我必须停止异步拖动。我可以在拖动事件中添加一些东西来取消拖动吗?

document.querySelector('#drag-elem').addEventListener('drag', function(e)
  // Stop the drag
  e.preventDefault();
)

document.querySelector('#drag-elem').addEventListener('dragstart', function(e)
  console.log('dragstart')
)
<div draggable='true' id='drag-elem'>Draggable</div>

【问题讨论】:

为什么要在拖动过程中停止拖动?为什么不通过删除可拖动属性来防止它呢? 顺便提一下,用户可以在拖动过程中按Escape取消拖动。 谢谢科尔。它发生了一种异步验证,我们在 dragstart 事件完成后获取验证数据。 【参考方案1】:

您可以使用dataIsValid 标志来决定在ondragoverondrop 事件处理程序中是否允许放置。这里是一个例子,数据是 0 到 1 之间的随机数,大于 0.5 时认为有效,异步验证需要一整秒。尝试将 Source 拖到 Target 上并等待至少一秒钟,然后松开鼠标左键。

let dataIsValid = false;

function validateData(data) 
  dataIsValid = data.value > 0.5;
  console.log(`Data is $dataIsValid ? "valid" : "invalid": $data.value.toFixed(2)`);


function onDragStart(event) 
  // Create data to be transferred
  const data = 
    value: Math.random()
  ;
  event.dataTransfer.setData("text", JSON.stringify(data));
  event.target.textContent = data.value.toFixed(2);
  
  // Start asynchronous validation
  dataIsValid = false;
  setTimeout(() => validateData(data), 1000);


function onDragOver(event) 
  if (dataIsValid) 
    event.preventDefault();  
  


function onDrop(event) 
  if (dataIsValid) 
    event.preventDefault();  
    const data = JSON.parse(event.dataTransfer.getData("text"));
    event.target.textContent = data.value.toFixed(2);
  
div.circle 
  display: inline-block;
  width: 100px;
  height: 100px;
  border-radius: 50px;
  text-align: center;
  vertical-align: middle;
  line-height: 100px;
  font-family: Arial, Helvetica, sans-serif;


div#source 
  background: coral;


div#target 
  background: lightblue;
<div id="source" class="circle" draggable="true" ondragstart="onDragStart(event)">Source</div>
<div id="target" class="circle" ondragover="onDragOver(event)" ondrop="onDrop(event)">Target</div>

【讨论】:

感谢 kol ,尽管我的意图是取消下降。这似乎是不可能的。喜欢这种维护全局状态并使 drop 无效的想法。 不客气。我认为这是不可能的,因为它可能会使用户感到困惑。想象一下,您开始拖动,然后被拖动的对象突然从鼠标指针下方消失,尽管您仍然按住左键。我想我不小心松开了按钮,所以我会再次尝试拖动。

以上是关于开始拖拽一个带有 draggable 属性的 DOM 元素后,我们可以停止拖拽并退出拖拽操作吗?的主要内容,如果未能解决你的问题,请参考以下文章

Vue 也能实现拖拽了 (Draggable)

HTML5拖拽实例

jQuery 工具类函数

H5 的 Draggable 属性

Vue3与Vue.draggable-next拖拽问题

Vue.Draggable 心得