可抛出两次的可放置小部件的jQuery UI drop事件

首先,我知道这个问题之前已经被问过,无论是在这个网站还是其他网站,但答案都是我的场景的垃圾(如果它们不完全是垃圾),并且(至少对于这里的问题: jQuery UI drop event可抛出的火灾可以排序 ),建议只是关闭.sortable完全,这肯定不是我想要做的。

好吧,我有这个jquery(请记住,如果任何选项或html ID看起来很傻,这只是为了测试,所以我可以尝试解决这个问题):

 $(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(); }); 

这是有效的标记:

 
  • Drag me down
  • Drag this down, too
  • Drag this down, also
  • Drag this down, as well
  • Drag this down, too
  • Drag this down, too
  • Drag this down, too
  • Drag this down, click
  • Drag this down, clicky
  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5

我没有重叠的sortable div或类似的东西,我想我明白‘为什么’这种情况发生了(因为sortable默认情况下得到draggables属性?),我似乎无法做任何事情。

问题当然是……

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

……只需要一次,就会被触发两次。

我认为这个问题会有一个简单的解决方案,因为如果这个问题需要一堆复杂的脚本来修复,那么我认为这些特殊的jquery小部件不值得一试。 也许我只是困惑?

这是在同一元素上同时使用sortabledroppable的已知问题。

您可以使用sortablereceive事件。

jsFiddle演示

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

我有类似的问题。 有2个可放置元素,其中一个有相对位置,另一个 – 绝对。 它们不是嵌套的,但是具有绝对位置的那部分的一部分位于具有相对位置的部分之上(在jQuery docs中,这被称为“相交”)。 当我将可拖动元素移动到“绝对”可放置时,drop事件被触发两次。 我已经搜索了几天,但没有找到任何解决方案。

然后我决定做一个简单的一般解决方法。 看起来不是很吸引人,但这有助于在任何情况下发射2次跌落事件。

 drop: function( e, ui ) { if ( ! $('.already-dropped').length ) { $('body').addClass('already-dropped'); setTimeout( function() { $('.already-dropped').removeClass('already-dropped'); }, 100 ); // callback code... } } 

也许我有点太晚了,但我发布这个希望它会帮助某人。 这是我使用的代码。 基本上,如果函数被调用两次,它们之间的间隔应该很快(比人们通常做的快),所以我将数字设置为200毫秒。

我使用localStorage设置一个名为“last_call”的变量。 这是调用函数的时间。 在下一个调用中,我们将检查该函数是否先前已被调用。 如果未调用,则该函数将继续执行。 如果它被调用,我们将检查它上次被调用的时间。 如果它在200毫秒内被调用(显然是机器通话,而不是人为通话),我们将不会再次调用它。

  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);