2013-04-05 18 views
31

Próbuję znaleźć sposób na przekazanie obiektu macierzystego za pośrednictwem zdarzenia event.dataTransfer języka JavaScript do przeciągania i upuszczania. Piszę część edytora front-end CMS-a i chcę, żeby użytkownicy mogli przeciągać i upuszczać elementy (wielu różnych typów, od plików po obrazy, aż po fragmenty kodu HTML do niemal wszystkiego). Dlatego chcę przekazać rzeczywisty obiekt, więc mogę dołączyć do niego dane, aby określić rzeczy, które będą konieczne, aby wiedzieć, jak je renderować.Prześlij obiekt przez dane Transfer do domeny

Jednym z obejść jest użycie jQuery's .data() w celu dołączenia obiektu do czegoś innego na stronie, a następnie po prostu przekazanie łańcucha selektora w setData ... ale nie podoba mi się ten hack.

Może to również zostać rozwiązane przez przeciąganie/zrzucanie interfejsu jQuery UI (i nie jestem całkowicie przeciwny używaniu jakichkolwiek bibliotek), ale ponieważ dropzone znajduje się w elemencie iframe, jest to faktycznie udokumentowany błąd w najnowszym interfejsie jQuery (1.10.2). Ponadto zdecydowanie wolałbym to robić natywnie, jeśli to możliwe. W tej aplikacji jest już wystarczająco dużo bibliotek.

Oto problem: 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 
}); 

Teraz, po przeczytaniu specyfikacji, I całkowicie zrozumieć, dlaczego to się nie powiedzie. Czego nie rozumiem, to, jak ostatecznie osiągnąć to, czego chcę.

Dzięki

+0

Chyba wystarczy stringify dane przed wysłaniem go i JSON.parse dane po otrzymaniu. – Deee

Odpowiedz

36

Należy przekazać obiekt do JSON.stringify przed użyciem setData ponieważ można przechowywać tylko łańcuchy.

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

I na odwrót trzeba przestawienia ciąg do obiektu:

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

Zobacz this Fiddle

pracy
+2

Rozważyłem to również po tym, jak napisałem, choć nadal mam wrażenie, że powinien istnieć sposób na przekazanie obiektu? – sarink

+1

Nie sądzę, że istnieje sposób. ale możesz dodać globalną tablicę, w której przechowujesz dane, a następnie po prostu przekazujesz klucz do 'set/getData'. Może szybciej dla większych obiektów –

+1

Tak, zaproponowałem ten pomysł w początkowym pytaniu. Naprawdę liczyłem na to, że w jakiś sposób uda się przekazać prawdziwy obiekt. Wydaje się trochę dziwne, że nie będzie to zawarte w specyfikacji drag n drop. Sądzę, że po prostu poprzestanę na stringify lub globalnej tablicy ... – sarink

2

Może to, co mam zamiar zasugerować jest źle (jeśli tak ja chętnie usłyszę dlaczego). Dlaczego nie ustawić zmienną w słuchacza dragstart odwołać, co trzeba, na przykład:

//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 = :(.. Istnieje wiele trywialnych obejść w ten sposób.Pierwotnie wysłałem pytanie, ponieważ chciałem wiedzieć, czy można przekazać obiekt poprzez data Transfer. Okazuje się, że nie możesz. – sarink

+0

@Kabir, ale jest to bardziej poprawny sposób niż serializacja/deserializacja, z dokumentów, które powinny być w stanie zobaczyć, że dane pochodzą z https://developer.mozilla.org/en-US/docs/Web/API/DOMString – 2oppin

Powiązane problemy