2016-08-06 33 views
6

Momentan arbeite ich an einem Szenario, das ich brauche, um die Daten zu ändern, die einem ziehenden Element angehängt werden, nachdem das Ziehen begonnen hat. Grundsätzlich sind die Drop-Zones Eingabefelder oder Textfelder, also würde ich gerne das native event.dataTransfer.setData verwenden, da der native Drag-Drop den Caret mit der Maus bewegen kann.Event.dataTransfer kann asynchron nach Drag-Start gesetzt werden?

Alles funktioniert perfekt am Anfang, wenn ich nur setData() synchron im Listener von dragstart Ereignis aufrufen.

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

Allerdings könnte mein Szenario sein, dass die Daten von einer asynchronouly Callback-Funktion ist wie eine AJAX-Anforderung. Dann versuchte ich setData() in dieser Rückruffunktion aufzurufen, aber nichts scheint erfolgreich eingestellt zu sein.

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) 

}) 

Ich habe auch versucht, die Daten in dragenter und sogar drop Ereignis-Listener des Drop-Zones zu ändern. Aber es gab immer noch kein Glück.

Diese plunker zeigt, was ich versucht habe.

Dann habe ich auf die MDN API document verwiesen, um offizielle api Beschreibung des dataTransfer Objekts zu finden. Aber es gibt nichts über Probleme wie asynchrone Verwendung von nach Drag-Start. Eine wirklich seltsame Sache ist, dass, wenn ich versuche, die beiden dataTransfer Referenzen in dragstart und drop Ereignis zu vergleichen, die sind nicht das gleiche Objekt. Jetzt habe ich keine Ahnung, was tatsächlich passiert.

So sind meine Fragen

  1. Ist es möglich, die Daten in dataTransfer einstellen, nachdem das Ziehen mit dem nativen APIs gestartet (ohne event.preventDefault zu verwenden)?
  2. Wenn die erste Frage die Antwort NEIN ist, welche Art von Workaround könnte ich versuchen? Ich könnte mir etwas überlegen, wie ich die Daten speichern und die Daten übertragen kann. Mein Hauptanliegen ist, dass, wenn event.preventDefault() auf drop verwendet wird, es nicht einfach ist, das Caret mit der Maus zu bewegen, wie das native Ablegen tut.
+0

für Konsolen-GO Was ist Zweck 'event.dataTransfer' asynchron der Einstellung? Was versuchst du zu erreichen? – guest271314

Antwort

1

Hier ist Ihre Antwort. Erstens, Sie können nur Daten in Ihrem Dragstart Ereignis festlegen. Also, jedes Mal, wenn Dragstart Ereignis startet, legt es Wert und was auch immer Sie asynchron einstellen wird nicht reflektiert, egal was.

Also, eine Sache, die Sie tun können, ist ein globales Objekt haben und festgelegt, dass auf Drag Startereignis wie folgt aus:

var someObj = { 
    asd : 'something' 
} 

und in Ihnen drag Rückruf gesetzt, wie folgt aus:

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) 

    })  

Objekt ist standardmäßig Referenztyp. Nun können Sie someObj.asd auf einen beliebigen Wert setzen, und Sie werden einen neuen Wert sehen. Aber es gibt ein Problem mit diesem Ansatz, Wert wird reflektiert, nachdem der Fall passiert ist, nachdem das Ereignis beendet wurde.

Also, Ihr Problem zu lösen, was Sie tun können, wird keinen Wert auf drag setzen nur einen Wert zu someObj.asd auf Drag Start- und verwenden auf Drop someObj.asd. Hier

ist ein Link von dem, was ich versuche zu erklären: https://plnkr.co/edit/SZhI9lGRI37eEd1nWfhn?p=preview

siehe Konsole auf Drop-Ereignis Sie reflektiert Wert dort sehen.

SEHE NICHT NUR UI

+0

Danke für Ihre Antwort. Speichern in einem globalen Objekt ist eine gute Idee. Aber was ich erreichen möchte, ist, den gespeicherten Text in diesen Textbereich oder einen editierbaren Div-Inhalt an der Cursorposition einzufügen (die Mausposition wie bei der nativen Position zu verfolgen). Nachdem ich der ersten Frage ein NEIN gegeben habe, ist das entscheidende Problem der Problemumgehung, wie kann ich das globale Objekt beim Ablegen verwenden, um den Text an der richtigen Stelle einzufügen. – MMhunter

+0

können Sie Javascript schreiben, um das für Sie zu tun. –

+0

Nun, das ist wahr. Aber ich werde nicht so kämpfen, wenn das leicht gemacht werden kann. Ich kann auch keine Bibliothek finden, die mir hilft, das zu erreichen. Ich bin also immer noch mit diesem Problem konfrontiert und kann keinen Weg finden, es mit Ihrer aktuellen Antwort zu lösen. Ich brauche die UI, um richtig zu aktualisieren. – MMhunter