2013-04-05 19 views
31

Sto cercando di capire come passare un oggetto nativo tramite event.dataTransfer di javascript per il trascinamento della selezione. Sto scrivendo la porzione di front-end editor di un CMS e voglio che gli utenti siano in grado di trascinare e rilasciare elementi (di molti tipi diversi, che vanno dai file alle immagini ai frammenti di HTML fino a qualsiasi cosa). Ecco perché voglio passare un oggetto reale, quindi posso allegare dei dati ad esso per specificare le cose che saranno necessarie per sapere come renderlo.Passare l'oggetto tramite dataTransfer

Una soluzione è quella di utilizzare .data di jQuery() per collegare un oggetto a qualcos'altro sulla pagina, e poi semplicemente passare la stringa di selezione in setData ... ma io non particolarmente godere di quella mod.

Questo potrebbe anche essere risolto con jQuery UI trascinabili/droppable (e io non sono assolutamente contrario a utilizzare le librerie), ma dal momento che la zona di lancio è in un iframe, questa è una realtà un problema documentato nell'ultima UI jQuery (1.10.2). Inoltre, preferirei fortemente farlo in modo nativo se possibile. Ci sono già abbastanza librerie in questa app.

Ecco il problema: http://jsfiddle.net/AHnh8/

var foo = {foo: "foo", bar: "bar"}; 

$dragme.on("dragstart", function(e) { 
    e.originalEvent.dataTransfer.setData("foo", foo); 
}); 

$dropzone.on("dragenter", function(e) { e.preventDefault(); }); 
$dropzone.on("dragover", function(e) { e.preventDefault(); }); 
$dropzone.on("drop", function(e) { 
    console.log(e.originalEvent.dataTransfer.getData("foo")); // [Object object] 
    console.log(typeof e.originalEvent.dataTransfer.getData("foo")); // string 
}); 

Ora, dopo aver letto le specifiche, ho completamente capire perché questo non riesce. Quello che non capisco, è come ottenere in definitiva ciò che voglio.

Grazie

+0

penso non vi resta che stringa i dati prima di inviarli e JSON.parse i dati alla ricezione. – Deee

risposta

36

Si dovrebbe passare l'oggetto a JSON.stringify prima di utilizzare setData perché si può solo memorizzare le stringhe.

var j = JSON.stringify(foo); 
e.originalEvent.dataTransfer.setData("foo", j); 

E viceversa si deve riconvertire la stringa da un oggetto:

var obj = JSON.parse(e.originalEvent.dataTransfer.getData("foo")); 
console.log("foo is:", obj); 

Vedi this Fiddle

lavoro
+2

Avevo preso in considerazione anche questo dopo aver postato, anche se ho ancora la sensazione che ci dovrebbe essere un modo per passare un oggetto? – sarink

+1

non penso ci sia un modo. ma è possibile aggiungere un array globale in cui archiviare i dati e quindi passare semplicemente la chiave a 'set/getData'. Forse è più veloce per oggetti più grandi –

+1

Sì, ho proposto questa idea nella domanda iniziale. Speravo davvero che ci fosse un modo per passare un oggetto reale in qualche modo. Sembra un po 'strano che non sia incluso nella specifica drag n drop. Immagino che mi accontenterò solo del stringify o dell'array globale ... – sarink

2

Forse quello che sto per suggerire è sbagliato (se così mi sarà felice di sentire perché). perché non impostare una variabile in chi ascolta dragstart fare riferimento a ciò che è necessario, per esempio:

//global variable 
var obj; 

//set the global variable to wahtever you wish in the dragstart: 
$dragme.on("dragstart", function(e) { 
    obj = foo; 
    //or even obj = document.getElementById("some element's id"); 
}); 

//use this obj in the drop listener. 
$dropzone.on("drop", function(e) { 
    obj.doWahtEver(); 
}); 
+3

bc globals = :(.. Ci sono un sacco di soluzioni alternative banali come questa.Inizialmente avevo postato la domanda perché volevo sapere se si poteva passare un oggetto attraverso dataTransfer. Si scopre che non puoi. – sarink

+0

@Kabir, tuttavia è il modo più corretto di serializzare/deserializzare, dai documenti dovresti essere in grado di vedere che fromat dei dati è https://developer.mozilla.org/en-US/docs/Web/API/DOMString – 2oppin

Problemi correlati