2013-04-05 32 views
31

Tôi đang cố gắng tìm ra cách để truyền đối tượng gốc thông qua event.dataTransfer của javascript để kéo và thả. Tôi đang viết phần trình chỉnh sửa đầu cuối của CMS và muốn người dùng có thể kéo và thả các phần tử (trong nhiều loại khác nhau, từ tệp đến hình ảnh tới các đoạn mã HTML đến bất kỳ thứ gì). Đó là lý do tại sao tôi muốn truyền một đối tượng thực, vì vậy tôi có thể đính kèm dữ liệu vào nó để xác định những thứ cần thiết để biết cách render nó.Vượt qua đối tượng qua dataTransfer

Một giải pháp khác là sử dụng .data của jQuery() để đính kèm đối tượng vào một thứ khác trên trang và sau đó chỉ cần chuyển chuỗi chọn trong setData ... nhưng tôi không đặc biệt tận hưởng việc hack đó.

Điều này cũng có thể được giải quyết với jQuery UI có thể kéo được/có thể tháo rời (và tôi hoàn toàn không phản đối việc sử dụng bất kỳ thư viện nào), nhưng vì dropzone nằm trong iframe, đây thực sự là lỗi được ghi trong giao diện người dùng jQuery mới nhất (1.10.2). Ngoài ra, tôi rất muốn làm điều đó một cách tự nhiên nếu có thể. Đã có đủ thư viện trong ứng dụng này.

Dưới đây là các vấn đề: 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 
}); 

Bây giờ, sau khi đọc thông số kỹ thuật, tôi hoàn toàn hiểu tại sao điều này thất bại. Những gì tôi không hiểu, là làm thế nào để cuối cùng đạt được những gì tôi muốn.

Cảm ơn

+0

Tôi nghĩ rằng bạn chỉ cần stringify dữ liệu trước khi gửi nó và JSON.parse dữ liệu khi nhận được. – Deee

Trả lời

36

Bạn phải vượt qua các đối tượng để JSON.stringify trước khi sử dụng setData bởi vì bạn chỉ có thể lưu trữ chuỗi.

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

Và theo chiều ngược lại, bạn phải chuyển đổi lại chuỗi đến một đối tượng:

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

Xem this làm việc Fiddle

+2

Tôi cũng đã xem xét điều này sau khi tôi đăng, mặc dù tôi vẫn cảm thấy như có nên có một cách để vượt qua một đối tượng? – sarink

+1

tôi không nghĩ rằng có một cách. nhưng bạn có thể thêm một mảng toàn cục, nơi bạn lưu trữ dữ liệu của bạn và sau đó chỉ cần chuyển khóa tới 'set/getData'. Có lẽ nó là nhanh hơn cho các đối tượng lớn hơn –

+1

Vâng, tôi đã đề xuất ý tưởng đó trong câu hỏi ban đầu. Đã thực sự hy vọng có một cách để vượt qua một đối tượng thực sự bằng cách nào đó. Dường như kỳ quặc rằng điều đó sẽ không được bao gồm trong thông số kéo thả n. Tôi đoán tôi sẽ chỉ giải quyết cho stringify hoặc mảng toàn cầu ... – sarink

2

Có lẽ những gì tôi sắp đề nghị là sai (nếu vì vậy tôi sẽ rất vui khi được nghe lý do tại sao). Tại sao không thiết lập một biến trong người nghe dragstart để tham khảo những gì bạn cần, ví dụ:

//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 = :(.. Có rất nhiều cách giải quyết tầm thường như thế này.Ban đầu tôi đã đăng câu hỏi bởi vì tôi muốn biết liệu bạn có thể truyền một đối tượng thông qua dataTransfer hay không. Hóa ra bạn không thể. – sarink

+0

@Kabir, nhưng đó là cách chính xác hơn sau đó tuần tự hóa/deserialize, từ các tài liệu bạn sẽ có thể thấy rằng fromat dữ liệu là https://developer.mozilla.org/en-US/docs/Web/API/DOMString – 2oppin

Các vấn đề liên quan