是否可以在拖动开始后异步设置event.dataTransfer

Possible to set event.dataTransfer asynchronously after drag start?

本文关键字:异步 设置 event dataTransfer 开始 拖动 是否      更新时间:2023-09-26

当前我正在处理一个场景,需要在拖动开始后更改附加到拖动元素的数据。基本上,拖放区域是输入字段或文本区域,所以我想使用原生event.dataTransfer.setData,因为原生拖放可以使插入符号随鼠标移动。

如果我只是在dragstart事件的监听器中同步调用setData(),那么一开始一切都很完美。

dragItem.addEventListener("dragstart",function(event){  
     event.dataTransfer.setData("text/plain","data set in dragstart");
}) 

然而,我的场景可能是数据来自异步回调函数,比如AJAX请求。然后我尝试在这个回调函数中调用setData(),但似乎没有成功设置任何内容。

dragItem.addEventListener("dragstart",function(event){
  event.dataTransfer.setData("text/plain","data set in dragstart");
  //like a callback in Ajax or resolve function of a promise.
  setTimeout(function(){
    console.log("attempt to set data asynchonrously after drag start");
    event.dataTransfer.setData("text/plain","asynchonrously set data");
    //looks like failed, the console output is empty, even not the original set one
    console.log(event.dataTransfer.getData("text/plain"));
  },200)
}) 

我还尝试更改丢弃区域的dragenter甚至drop事件侦听器中的数据。但是仍然没有运气。

这个plunker展示了我所尝试的。

然后,我参考了MDN API文档来查找dataTransfer对象的正式API描述。但是在拖动启动后异步使用setData并没有什么问题。一件非常奇怪的事情是,如果我试图比较dragstartdrop事件中的两个dataTransfer引用,它们不是同一个对象。现在我不知道实际发生了什么。

所以我的问题是

  1. 在使用本机API(不使用event.preventDefault(开始拖动后,是否可以在dataTransfer中设置数据
  2. 如果第一个问题的答案是否定的,我可以尝试什么样的变通方法我可以考虑一下如何保存和传输数据。我主要担心的是,如果在drop上使用event.preventDefault(),那么就不容易像本地拖放那样用鼠标移动插入符号

这是您的答案。首先,您只能在dragstart事件中设置数据。因此,每当dragstart事件启动时,它都会设置值,而无论怎样,异步设置的内容都不会得到反映。

所以,你可以做的一件事是有一个全局对象,并在拖动开始事件时设置它,如下所示:

var someObj = {
   asd : 'something'
}

并在dragstart回调中设置,如下所示:

dragItem.addEventListener("dragstart",function(event){
      event.dataTransfer.setData("text/plain", someObj.asd);
      dataTransferObject = event.dataTransfer;
      setTimeout(function(){
        console.log("attempt to set data asynchonrously after drag start");
        //event.dataTransfer.setData("text/plain","asynchonrously set data");
        someObj.asd = 'asynchonrously';
        //looks like failed, the console output is empty
        console.log(event.dataTransfer.getData("text/plain"));
      }, 100)
    })    

对象默认为引用类型。现在,您可以将someObj.asd设置为您想要的任何值,您将看到反映的新值。但这种方法有一个问题,价值将在下降发生后反映,也就是在事件结束后。

因此,要解决您的问题,您可以做的是不要在dragstart上设置任何值,只需在拖动启动时将一些值设置为someObj.asd,并在拖放时使用omeObj.asd

以下是我试图解释的内容的链接:https://plnkr.co/edit/SZhI9lGRI37eEd1nWfhn?p=preview

请参阅控制台下拉事件您将在其中看到反映的值。

不要看到UI只是去控制台