Is it possible to set event.dataTransfer asynchronously after the start of the drag and drop?

I am currently working on a script that I need to change the data attached to the drag and drop element after the start of the drag and drop. Basically, drag and drop zones are input or text fields, so I would like to use my own event.dataTransfer.setData , since my own drag-drop can make the carriages move with the mouse.

Everything works fine in the beginning if I just call setData() synchronously in the dragstart event listener.

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

However, my scenario may be that the data comes from an asynchronous callback function, such as an AJAX request. Then I tried to call setData() on this callback function, but nothing was successfully installed.

 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) }) 

I also tried changing the data in dragenter and even drop event listeners of the reset zones. But still no luck.

This plunker shows what I tried.

I then referred to the MDN API document to find the official api description of the dataTransfer object. But there is nothing about issues like asynchronously using setData after the start of the drag and drop. It is very strange that if I try to compare two dataTransfer links in a dragstart and drop event, they are NOT the same object. Now I do not know what is really happening.

So my questions

  • Is it possible to set data in dataTransfer after the start of the drag using its own APIs (without using event.preventDefault )?
  • If the first answer to the question is “NO”, what workaround can I try? I might think about how to save and receive data for transmission. My main concern is that if event.preventDefault() used on drop , it is not easy to make the carriage move with the mouse, as does a native reset.
+6
source share
1 answer

Here is your answer. Firstly, you can only set data in dragstart . Thus, every time a dragstart event is fired , it sets a value, and what you ever set asynchronously will not be reflected on anything.

So, one thing you can do is to have a global object and set that if you start the drag and drop:

 var someObj = { asd : 'something' } 

and set your dragstart callback, for example:

 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) }) 

The object defaults to the link type. Now you can set someObj.asd for any value you want and see the new value. But there is a problem with this approach, the value will be reflected after the fall occurs after the completion of the event.

So, to solve your problem, you cannot set the dragstart value, just set some someObj.asd value when you start the drag and drop, and use someObj.asd when deleting.

Here is a link to what I'm trying to explain: https://plnkr.co/edit/SZhI9lGRI37eEd1nWfhn?p=preview

see the console on the drop event , you will see the displayed value there.

DO NOT SEE UI JUST GO FOR CONSOLE

+1
source

All Articles