34

Xin lỗi của tôi nếu điều này được trả lời trong một câu hỏi khác, tôi không thể tìm thấy câu trả lời cụ thể cho vấn đề của mình!Kéo và thả jQuery - kiểm tra để thả bên ngoài một giọt có thể rơi xuống

Tôi đang cố gắng kiểm tra xem một jQuery có thể kéo được thả ra ngoài một phân đoạn hợp pháp hay không. Điều này thường sẽ được giải quyết 90% thời gian bằng cách hoàn nguyên khả năng kéo, nhưng tôi không muốn làm điều đó. Thay vào đó, tôi muốn làm một việc nếu draggable được thả xuống một droppable (làm việc tuyệt vời!), Và cái gì khác nếu nó được thả bên ngoài của tất cả droppables có thể (hiện đang nhận được tốt hơn của tôi!).

Tóm lại:

jQuery('#droppable').droppable(
{ 
    accept: '#draggable', 
    drop: function(event, ui) 
    { 
     // awesome code that works and handles successful drops... 
    } 
}); 

jQuery('#draggable').draggable(
{ 
    revert: false, 
    stop: function() 
    { 
     // need some way to check to see if this draggable has been dropped 
     // successfully or not on an appropriate droppable... 
     // I wish I could comment out my headache here like this too... 
    } 
}); 

tôi cảm thấy như tôi là thiếu một cái gì đó thực sự rõ ràng ... cảm ơn trước sự giúp đỡ nào!

Trả lời

52

Bởi vì cháy thả sự kiện của droppable trước khi sự kiện dừng của kéo, tôi nghĩ rằng bạn có thể đặt một lá cờ trên phần tử bị kéo trong trường hợp thả như vậy:

jQuery('#droppable').droppable(
{ 
    accept: '#draggable', 
    drop: function(event, ui) 
    { 
     ui.helper.data('dropped', true); 
     // awesome code that works and handles successful drops... 
    } 
}); 

jQuery('#draggable').draggable(
{ 
    revert: false, 
    start: function(event, ui) { 
     ui.helper.data('dropped', false); 
    }, 
    stop: function(event, ui) 
    { 
     alert('stop: dropped=' + ui.helper.data('dropped')); 
     // Check value of ui.helper.data('dropped') and handle accordingly... 
    } 
}); 
+3

Giải pháp rất tuyệt vời Luke, cảm ơn vì điều này ... làm việc như một sự quyến rũ! –

+0

Tuyệt vời nhưng: Có tài liệu nào cho .data không? Đối với tôi, nó xuất phát từ thiên đường: 3 (đọc: không thể tìm thêm thông tin) – yoshi

+0

http://api.jquery.com/jQuery.data/ –

4

Cố gắng sử dụng sự kiện "out" của một yếu tố droppable.

Đây là documentation

"Sự kiện này được kích hoạt khi một kéo chấp nhận được kéo ra (nằm trong dung sai) droppable này." Nếu tôi đúng, đây là những gì bạn cần.

Điều gì cũng có thể là tạo lớp phủ phần tử trên toàn bộ trang. Nếu phần tử bị bỏ ở đó, bạn sẽ kích hoạt sự kiện của mình. Không phải là tốt nhất, nhưng tôi nghĩ rằng cách duy nhất để làm điều đó. Vì bạn cần một số vật phẩm "có thể phân hủy" khác để kích hoạt các sự kiện này.

+0

Xin chào ggzone, cảm ơn phản hồi nhanh ... nó sẽ là hoàn hảo nếu khả năng kéo tôi đang kéo ra khỏi thùng rác hợp lệ. Nếu một vật thể kéo được kéo từ vị trí ban đầu của nó và sau đó rơi xuống một nơi nào đó cách xa một cách ngẫu nhiên từ một vật lộn có thể hợp pháp, thì sự kiện này sẽ không bao giờ bị sa thải, theo như tôi biết! –

+0

Tôi đã chỉnh sửa câu trả lời của mình cho bạn – ggzone

+0

Thật tuyệt vời, cảm ơn ggzone ... như bạn đã nói, có lẽ không phải là tốt nhất, và nếu bạn chưa thấy câu trả lời do Luke cung cấp, tôi nghĩ nó cung cấp một giải pháp thanh lịch hơn với cùng các kết quả! –

9

Tôi thấy rằng bạn đã có một câu trả lời ; anyway tôi có vấn đề này cùng hôm nay và tôi giải quyết nó theo cách này:

var outside = 0; 

// this one control if the draggable is outside the droppable area 
$('#droppable').droppable({ 
    accept  : '.draggable', 
    out   : function(){ 
     outside = 1; 
    }, 
    over  : function(){ 
     outside = 0; 
    } 
}); 

// this one control if the draggable is dropped 
$('body').droppable({ 
    accept  : '.draggable', 
    drop  : function(event, ui){ 
     if(outside == 1){ 
      alert('Dropped outside!'); 
     }else{ 
      alert('Dropped inside!'); 
     } 
    } 
}); 

tôi cần điều đó bởi vì tôi không thể thay đổi các tùy chọn của draggables của tôi, vì vậy tôi đã phải chỉ làm việc với droppables (Tôi cần nó bên trong tuyệt vời FullCalendar plugin). Tôi cho rằng nó có thể có một số vấn đề bằng cách sử dụng tùy chọn "tham lam" của droppables, nhưng nó sẽ làm việc trong hầu hết các trường hợp.

PS: xin lỗi vì tiếng anh xấu của tôi.

EDIT: Như đã đề xuất, tôi đã tạo phiên bản bằng cách sử dụng jQuery.data; nó có thể được tìm thấy ở đây: jsfiddle.net/Polmonite/WZma9/

Dù sao tài liệu jQuery.data nói:

Lưu ý rằng phương pháp này hiện không cung cấp hỗ trợ đa nền tảng cho việc thiết lập dữ liệu trên các tài liệu XML, như Internet Explorer không cho phép dữ liệu được đính kèm thông qua các thuộc tính expando.

(nghĩa là nó không hoạt động trên IE trước 8)

EDIT 2: Theo ghi nhận của @Darin Peterson, mã trước đó không làm việc với hơn một phần diện tích thả ; điều này sẽ khắc phục vấn đề đó: http://jsfiddle.net/Polmonite/XJCmM/

EDIT 3: Ví dụ từ EDIT 2 có lỗi. Nếu tôi kéo "Kéo tôi!" đến đáy có thể phân hủy, sau đó thả "Kéo tôi quá" xuống phía trên có thể phân hủy và sau đó thả "Kéo tôi quá" bên ngoài, nó cảnh báo "Bỏ bên trong!" Vì vậy, không sử dụng nó.

EDIT 4: Như đã lưu ý bởi @Aleksey Gor, ví dụ trong Chỉnh sửa 2 là sai; trên thực tế, đó là một ví dụ để giải thích cách lặp qua tất cả các trình kéo/vật thể có thể kéo xuống được, nhưng tôi thực sự đã quên xóa các thông báo cảnh báo, vì vậy nó khá là khó hiểu. Here fiddle được cập nhật.

+0

Đẹp và đơn giản! Đó là một giải pháp tốt, đặc biệt là khi bạn không có quyền truy cập vào các đồ kéo. Tôi đã tự hỏi, bây giờ suy nghĩ về các vấn đề phạm vi có thể, nếu bạn có thể sử dụng '$ (" # droppable "). Dữ liệu (" bên ngoài ", đúng);' to 'mang' trạng thái của biến hơn thanh lịch? Giải pháp tốt đẹp mặc dù! Cảm ơn về thông tin bạn vừa nhập! :) –

+1

Chắc chắn rồi. Tôi đã thêm phiên bản bằng cách sử dụng jQuery.data cho câu trả lời;) Dù sao điều đó có nghĩa là không có IE7 (trong trường hợp ai đó quan tâm). – Polmonite

+0

Brilliant! Cảm ơn bạn đã nghiên cứu và câu trả lời mở rộng! +1 –

1

Ưu điểm của ví dụ sau đây, là bạn không cần phải thay đổi hoặc biết về mã droppable:

Thuộc tính Revert kéo có thể có một hàm (giá trị) {}. Một giá trị được chuyển thành đối số, cho biết helper đã được thả vào một phần tử (phần tử drop) hay 'false' nếu không bị rơi vào một phần tử (thả ra ngoài hoặc không được chấp nhận).

Lưu ý: bạn cần phải trả về giá trị bool đúng từ đó Revert chức năng, để nói với các helper để trở lại hay không (true/false). Đúng nghĩa là có, đưa người trợ giúp trở lại vị trí ban đầu của nó , bằng cách di chuyển nó trở lại trong một chuyển động chậm (out-of-the-box). Sai nghĩa là không, chỉ cần xóa trợ giúp một cách đột ngột. Thiết lập thuộc tính Revert để 'hợp lệ', là một shortcut nói

  • 'vâng, nếu bỏ ra ngoài, sau đó trở lại helper'
  • 'không, nếu giảm trên một yếu tố droppable và được chấp nhận, sau đó giết chết người trợ giúp ngay lập tức '.

Tôi đoán là bạn có thể thêm trợ giúp hiện tại vào vùng chứa có thể kéo với thuộc tính dữ liệu trong sự kiện bắt đầu. Sau đó nhặt nó lên trong chức năng hoàn nguyên từ thuộc tính dữ liệu. Sau đó, thêm một thuộc tính vào helper, cho biết nó có bị bỏ hay không. Sau đó, cuối cùng trong sự kiện dừng, hãy kiểm tra giá trị thuộc tính dữ liệu này và thực hiện những gì bạn dự định.

thứ tự của sự kiện/chức năng đòi hỏi phải kéo: khởi động trở lại ngừng

Đây có thể là một ví dụ:

jQuery('#draggable').draggable(
{ 
    start: function(event, ui) { 
     $(this).data('uihelper', ui.helper); 
    }, 
    revert: function(value){ 
     var uiHelper = (this).data('uihelper'); 
     uiHelper.data('dropped', value !== false); 
     if(value === false){ 
      return true; 
     } 
     return false; 
    }, 
    stop: function(event, ui) 
    { 
     if(ui.helper.data('dropped') === true){ 
      // handle accordingly... 
     } 
    } 
}); 

Bạn thậm chí có thể trở thành sự thật trong hàm Hoàn nguyên, và chỉ cần loại bỏ các helper trong sự kiện stop thay vào đó, tùy thuộc vào giá trị data ('dropped') với ui.helper.remove(). Hoặc bạn thậm chí có thể phát nổ nó với CSS3 nếu bạn vẫn còn một ngày tồi tệ;)

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