拖动启动后可以异步设置event.dataTransfer吗?

时间:2016-08-06 04:45:40

标签: javascript jquery html javascript-events drag-and-drop

目前我正在开发一个场景,我需要在拖动开始后更改附加到拖动元素的数据。基本上,拖放区域是输入字段或textareas,因此我想使用本机event.dataTransfer.setData,因为本机拖放可以使插入符号与鼠标一起移动。

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

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 document来查找dataTransfer对象的官方api描述。但是没有任何关于像拖动开始后异步使用setData这样的问题。一个非常奇怪的事情是,如果我尝试比较dataTransferdragstart事件中的两个drop引用,则它们不是同一个对象。现在我不知道实际发生了什么。

所以我的问题是

  1. 使用本机API(不使用dataTransfer)启动拖动后,是否可以在event.preventDefault中设置数据?
  2. 如果第一个问题的答案是否定的,我可以尝试哪种解决方法? 我可以想到如何保存并获取要传输的数据。我主要担心的是,如果在event.preventDefault()上使用drop,则使用鼠标移动插入符号并不容易,就像本机删除一样。

1 个答案:

答案 0 :(得分:1)

这是你的答案。 首先,您只能在 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 在drop上使用 someObj.asd

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

在放置事件中查看控制台,您将在那里看到反映值。

  

不要看到UI只能去控制台