我正试图找出一种通过javascript的event.dataTransfer传递本机对象进行拖放的方法。我正在编写CMS的前端编辑器部分,并希望用户能够拖放元素(许多不同类型,从文件到图像到HTML片段到几乎任何东西)。这就是为什么我想传递一个真实的对象,所以我可以附加数据来指定必要的东西,以便知道如何渲染它。
一种解决方法是使用jQuery的.data()将对象附加到页面上的其他内容,然后简单地在setData中传递选择器字符串......但我并不特别喜欢该hack。
这也可以通过jQuery UI的draggable / droppable解决(我并不完全反对使用任何库),但由于dropzone在iframe中,这实际上是最新jQuery UI中的文档错误( 1.10.2)。另外,如果可能的话,我更愿意本地做。这个应用程序中已经有足够的库。
问题在于: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
});
现在,在阅读了规范后,我完全理解为什么会失败。我不明白的是,如何最终实现我想要的目标。
由于
答案 0 :(得分:48)
在使用JSON.stringify
之前,您应该将对象传递给setData
,因为您只能存储字符串。
var j = JSON.stringify(foo);
e.originalEvent.dataTransfer.setData("foo", j);
反过来,你必须将字符串重新转换为对象:
var obj = JSON.parse(e.originalEvent.dataTransfer.getData("foo"));
console.log("foo is:", obj);
请参阅this工作小提琴
答案 1 :(得分:3)
也许我所暗示的是错误的(如果是这样,我会很高兴听到为什么)。 为什么不在dragstart监听器中设置一个变量来引用你需要的东西,例如:
//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();
});