2013-09-06 28 views
8

Trước tiên, tôi biết câu hỏi này đã được hỏi trước đây, cả trong trang web này và các trang khác, nhưng câu trả lời là tất cả rác cho kịch bản của tôi (nếu chúng không hoàn toàn rác) và (ít nhất là cho câu hỏi ở đây: jQuery UI drop event of droppable fires on sortable), đề xuất chỉ là tắt hoàn toàn .sortable, đó chắc chắn không phải là điều tôi muốn làm.Sự kiện thả xuống jQuery UI của tiện ích con có thể bị bắn hai lần

Được rồi, tôi có jquery này (lưu ý nếu bất kỳ tùy chọn hoặc id html trông ngớ ngẩn, đây chỉ là để thử nghiệm vì vậy tôi có thể thử và con số này ra):

$(function() { 
    $("#sortable").sortable({ 
     revert: true 
    }); 
    $("#draggable, #draggable2").draggable({ 
     connectToSortable: "#sortable", 
     helper: "clone", 
     revert: "invalid" 
    }); 

    $("#sortable").droppable({ 
     drop: function (event, ui) { alert("done been triggered."); } 
    }); 

    $("ul, li").disableSelection(); 
}); 

Và đây là hợp lệ đánh dấu:

<div class="objectPaletteHolder"> 
    <ul> 
     <li id="draggable" class="ui-state-highlight">Drag me down</li> 
     <li id="draggable2" class="ui-state-highlight">Drag this down, too</li> 
     <li id="draggable2" class="ui-state-highlight">Drag this down, also</li> 
     <li id="draggable2" class="ui-state-highlight">Drag this down, as well</li> 
     <li id="draggable2" class="ui-state-highlight">Drag this down, too</li> 
     <li id="draggable2" class="ui-state-highlight">Drag this down, too</li> 
     <li id="draggable2" class="ui-state-highlight">Drag this down, too</li> 
     <li id="draggable2" class="ui-state-highlight click">Drag this down, click</li> 
     <li id="draggable2" class="ui-state-highlight clicky">Drag this down, clicky</li> 
    </ul> 
</div> 
<div class="editContainer"> 
    <ul id="sortable"> 
     <li class="ui-state-default">Item 1</li> 
     <li class="ui-state-default">Item 2</li> 
     <li class="ui-state-default">Item 3</li> 
     <li class="ui-state-default">Item 4</li> 
     <li class="ui-state-default">Item 5</li> 
    </ul> 
</div> 

tôi không có chồng chéo sortable divs hoặc bất cứ điều gì như thế, và tôi nghĩ rằng tôi hiểu 'tại sao' này đang xảy ra (? vì sortable được draggables tính theo mặc định), tôi chỉ có thể không S eem để làm bất cứ điều gì về nó.

Vấn đề, tất nhiên, là ...

drop: function (event, ui) { alert("done been triggered."); } 

... được kích hoạt hai lần, khi nó chỉ cần một lần. Tôi sẽ nghĩ rằng sẽ có một giải pháp đơn giản cho vấn đề này, nếu vấn đề này đòi hỏi một loạt các kịch bản phức tạp để sửa chữa, hơn tôi nghĩ rằng các vật dụng jquery đặc biệt này sẽ không đáng giá. Có lẽ tôi chỉ bối rối?

+0

Thế còn câu hỏi thì sao? – Itay

+1

@Itay Theo yêu cầu: http://jsfiddle.net/dMen8/6/ – VoidKing

Trả lời

19

Đó là sự cố đã biết khi sử dụng cả hai sortabledroppable trên cùng một yếu tố.

Thay vào đó, bạn có thể sử dụng sự kiện 's receive'.

jsFiddle Demo

$("#sortable").sortable({ 
     revert: true, 
     receive: function (event, ui) {  
      alert("receive been triggered."); 
     } 
}).droppable({ }); 
+0

omg, đó là những gì tôi đã làm sau. Tôi đã chọn lọc tất cả các loại sự kiện trong ba vật dụng khác nhau, nhưng tôi đoán tôi không thấy "nhận" hoặc không nghĩ rằng nó được áp dụng cho những gì tôi đã làm sau đó. Dù sao, (câu trả lời này + bạn = quả bom-diggity). Cảm ơn, người đàn ông! – VoidKing

+0

Chỉ cần thông báo rằng nó được gắn vào phân loại, không phải là vật có thể phân tách được :) – Itay

+0

Thật vậy. Ngoài ra, tôi nhận thấy rằng bạn đã đính kèm '.droppable ({})' sau '.sortable' Có thể điều này/nên điều này được thực hiện riêng biệt? – VoidKing

-2

Có lẽ tôi là một chút quá muộn nhưng tôi đăng này hy vọng nó sẽ giúp một ai đó. Đây là mã tôi sử dụng. Về cơ bản, nếu hàm được gọi hai lần, khoảng cách giữa chúng sẽ nhanh chóng (nhanh hơn những gì con người thường làm) vì vậy tôi đặt số là 200 mili giây.

Tôi đã sử dụng localStorage để đặt biến được gọi là "last_call". Đó là lúc hàm được gọi. Trong cuộc gọi tiếp theo, chúng tôi sẽ kiểm tra xem chức năng đã được gọi trước đó chưa. Nếu nó không được gọi, hàm sẽ tiếp tục thực hiện. Nếu nó được gọi, chúng tôi sẽ kiểm tra khi nào lần cuối cùng nó được gọi. Nếu nó được gọi trong vòng 200 mili giây (rõ ràng là cuộc gọi máy, không phải là cuộc gọi của con người), chúng tôi sẽ không gọi lại.

var d = new Date(); 
    var this_time = d.getTime(); 
    if (localStorage.getItem("last_call") != null) 
    { 
     if ((this_time - parseInt(localStorage.getItem("last_call"))) < 100) 
     { 

      return; 
     } 

    } 
    localStorage.setItem("last_call", this_time); 
+3

Xin đừng làm điều này ... – Javier

+0

Bạn có thể giải thích lý do tại sao? – codingpuss

+0

@codingpuss về cơ bản bởi vì nó trông giống như thực hiện điên của riêng của setTimeout(). Nhưng ngay cả với setTimeout() nó sẽ là một hack nhưng không phải là một giải pháp gọn gàng. – walv

0

Tôi gặp sự cố tương tự. Có 2 yếu tố có thể phân hủy, một trong số chúng có vị trí tương đối và một yếu tố khác - tuyệt đối. Họ không được lồng nhau, nhưng một phần của một người có vị trí tuyệt đối nằm trên một phần của vị trí tương đối (trong tài liệu jQuery này được gọi là "giao nhau"). Khi tôi di chuyển một phần tử có thể kéo đến sự phân tách "tuyệt đối", sự kiện thả được cắt hai lần. Tôi đã tìm kiếm một vài ngày, nhưng không tìm thấy bất kỳ giải pháp nào.

Sau đó, tôi quyết định thực hiện một cách giải quyết chung đơn giản. Trông không hấp dẫn lắm, nhưng điều này sẽ giúp ích trong mọi tình huống với việc bắn 2 sự kiện.

drop: function(e, ui) { 
    if (! $('.already-dropped').length) { 
     $('body').addClass('already-dropped'); 
     setTimeout(function() { 
      $('.already-dropped').removeClass('already-dropped'); 
     }, 100); 
     // callback code... 
    } 
} 
Các vấn đề liên quan